replaceObjectAtIndex:i withObject:str is giving bad access error (also with remove object - even do i can addObject atIndex - nsmutablearray

I'm trying to replace a string in an array(update array) with a string found at an index of array(other array). Both arrays are initialized in init and i can nslog them in this method. if [str isEqualToString:[otherArray objectAtIndex:i] i want to return true/YES
but the line: [updateArray replaceObjectAtIndex:i withObject:str]; is giving bad access to program. (its only a console program) "Program received signal: “EXC_BAD_ACCESS”.
any suggestions appreciated, thanks trev
-(BOOL)checker:(NSString *)str {
NSLog(#"update arrayobject at %d is %#",0, [updateArray objectAtIndex:0]);
NSLog(#"otherArray size is %d",[otherArray count]);
NSLog(#"str iput is %#",str);
int i;
for (i=0; i<[otherArray count]; i++) {
if ([str isEqualToString:[otherArray objectAtIndex:i]]) {
[updateArray replaceObjectAtIndex:i withObject:str];
return TRUE;
}
}
return FALSE;
}

once check your array is it allocated or not properly..i think there is nothing more than that thing..

Related

How do i delete any item from a linked list?

I'm trying to write a function that deletes an element at a given position from a linked list, for now im using a linked list with only a head pointer. Now it may be that the user inputs a position that is larger than the size of the linked list so to remedy that i wrote this:
int delete(struct node** head, int pos)
{
struct node* temp = *head;
while(pos!=0 && temp->next!=NULL)
{
temp=temp->next;
pos--;
}
if(pos>0)
return 0;
}
but it gives the following error
fish: './a.out' terminated by signal SIGSEGV (Address boundary error)
i tried to debug it by writing a new code
int delete(struct node** head)
{
if((*head)->next==NULL)
return 1;
}
but it gives the same error
When head is NULL the evaluation of temp->next will give undefined behaviour or the error as you experienced.
However, there is more to correct to your function.
There is no deletion happening. To delete a node, its predecessor should have its next property update to point to the node after the removed node. The removed node should then be freed.
The value of *head should be modified when the first node of the list is removed.
The function should return an int, and so also when the deletion was successful (and pos == 0 after the loop), there should be a return that is executed, probably returning 1 to indicate success.
Not a problem, but I would advise using a different name for your function. If ever you move to C++, then delete will be a reserved word.
So:
int removeNode(struct node** head, int pos) {
if (*head == NULL) {
return 0;
}
struct node* temp = *head;
if (pos == 0) { // Case where first node must be removed
*head = (*head)->next; // Modify head reference
free(temp);
return 1; // Indicate success
}
while (pos > 1 && temp->next != NULL) {
temp = temp->next;
pos--;
}
if (pos != 1 || temp->next == NULL) {
return 0; // Invalid position
}
// Remove the node
struct node* prev = temp;
temp = temp->next;
prev->next = temp->next;
free(temp);
return 1; // Indicate success
}
as #paddy commented,
i didn't consider the case where head itself is pointing to NULL.
a simple if statement solved it
struct node* temp = *head;
if(temp==NULL){
printf("Empty LL\n");
free(temp);
return 0;
}

Member Variables in Class Get Blown Away When Using std::thread

I have defined a base class using std::thread. For the child class, I perform some initialization of member variables and then start the thread using m_thread.reset(new std::thread(&MyClass::ThreadMain, this)); where m_thread is a member of MyClass. The purpose of the class is to read data from a serial port and report to a parent. The posix message queue handle of the parent is passed to MyClass during initialization before the thread is created. On running I get exceptions and I see that member variables that were initialized before the thread started appear to be no longer valid using the watch in GDB.
It appears as if the first message on the serial port is received and passed validation in order to get to the SendToParent call. At this call, it appears that I lose the stack. I tried running cppcheck to see if I have any memory leaks or buffer overflows and found nothing.
void MyClass::ThreadMain(void)
{
ssize_t bytesRead = 0;
UINT8 buffer[256];
UINT8 message[256];
BOOL partialMessage = FALSE;
UINT8 messageIndex = 0;
UINT8 payloadLength = 0;
// read data from the UART
while(1)
{
// the UART is setup to pend until data is available
bytesRead = read(m_radioFileDescriptor, buffer, sizeof(buffer));
if (FAIL == bytesRead)
{
LOG_SYSTEM_INFO("UART Read interrupted by a system call");
}
else if (bytesRead > 0)
{
// build the message
for(ssize_t i = 0 ; i < bytesRead ; i++)
{
if (FALSE == partialMessage)
{
// have we found the start of the message?
if(START_BYTE == buffer[i])
{
// start of new message
messageIndex = 0;
message[messageIndex] = buffer[i];
partialMessage = TRUE;
messageIndex++;
}
}
else
{
// keep building the message until the expected length is reached
if(LENGTH_POSITION == messageIndex)
{
// capture the expected message length
message[messageIndex] = buffer[i];
messageIndex++;
payloadLength = buffer[i];
}
else
{
message[messageIndex] = buffer[i];
messageIndex++;
// check for expected length and end byte
if((messageIndex == payloadLength) && (END_BYTE == buffer[i]))
{
// this should be a valid message but need to confirm by checking for a valid checksum
UINT8 messageChecksum = message[messageIndex - CHKSUM_POS_FROM_END];
UINT8 calculatedChecksum = RadioProtocol::Instance().GenerateRadioChecksum(message, (payloadLength - CHKSUM_POS_FROM_END));
if (messageChecksum == calculatedChecksum)
{
SendToParent(message, payloadLength);
}
else
{
LOG_SYSTEM_ERROR("Checksum FAILURE");
}
// reset for the next message
partialMessage = FALSE;
messageIndex = 0;
}
else if((messageIndex == payloadLength) && (END_BYTE != buffer[i]))
{
// malformed message - throw out and look for start of next message
LOG_SYSTEM_ERROR("Bytes read exceeded expected message length");
partialMessage = FALSE;
messageIndex = 0;
}
}
}
} // end for loop of bytes read on the port
}
else
{
LOG_SYSTEM_INFO("Read returned 0 bytes which is unexpected");
}
}
}
void MyClass::SendToParent(UINT8* pMsg, UINT8 size)
{
if ((pMsg != NULL) && (m_parentQueueHandle > 0))
{
// message is valid - pass up for processing
MsgQueueMessage msgToSend;
msgToSend.m_msgHeader = UART_MESSASGE;
bzero(msgToSend.m_msgData, sizeof(msgToSend.m_msgData));
for (UINT8 i = 0; i < size; i++)
{
msgToSend.m_msgData[i] = pMsg[i];
}
if (FAIL == msgsnd(m_parentQueueHandle, &msgToSend, sizeof(msgToSend), IPC_NOWAIT))
{
LOG_SYSTEM_ERROR("FAILED to send message on queue");
}
}
}
This acts like I am performing a buffer overflow but I just can't see it. When I set a breakpoint at the line UINT8 messageChecksum = message[messageIndex - CHKSUM_POS_FROM_END]; all data in the watch window appear valid. If I step over to the next line then the data, m_parentQueueHandle as an example, gets blown away.
This is my first time working with c++11 threads and particularly with c++. Any help or insights would be appreciated.
I think I found the issue. I added a bunch of printfs and found that the destructor for the class was being called. Much further upstreamI had the parent object being created as a local variable and it was going out of scope. This caused the child to go out of scope but the threads were still running. I certainly need to clean up the threads in the destructor.

How to get installed application path for executable in COM

I am trying to get the installed location of all application using COM. I am able to get the display name of each application. But I am not able to get installed path of each application.
MY Code:
CComPtr<IShellItem> spPrinters;
CoInitialize(nullptr);
HRESULT hresult = ::SHCreateItemFromParsingName(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\"
L"::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr, IID_PPV_ARGS(&spPrinters));
CComPtr<IEnumShellItems> spEnum;
spPrinters->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&spEnum));
for (CComPtr<IShellItem> spProgram; spEnum->Next(1, &spProgram, nullptr) == S_OK; spProgram.Release())
{
CComHeapPtr<wchar_t> spszName;
spProgram->GetDisplayName(SIGDN_NORMALDISPLAY, &spszName);
CString cDisplayName = spszName;
}
Any idea how to get installed path from IEnumShellItems?
Here is a piece of code that will dump this out. The child's IPropertyStore does not return these, I don't know why, so we have to use the old
IShellFolder2::GetDetailsEx method with a special column id (which is the same as a PROPERTYKEY).
CComPtr<IShellItem> cpl;
CComPtr<IShellFolder2> folder;
CComPtr<IEnumShellItems> enumerator;
PROPERTYKEY pkLocation;
SHCreateItemFromParsingName(L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr, IID_PPV_ARGS(&cpl));
// bind to IShellFolder
cpl->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&folder));
// bind to IEnumShellItems
cpl->BindToHandler(NULL, BHID_EnumItems, IID_PPV_ARGS(&enumerator));
// get this property key's value
PSGetPropertyKeyFromName(L"System.Software.InstallLocation", &pkLocation);
for (CComPtr<IShellItem> child; enumerator->Next(1, &child, nullptr) == S_OK; child.Release())
{
// get child's display name
CComHeapPtr<wchar_t> name;
child->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
wprintf(L"%s\n", name);
// get child's PIDL
CComHeapPtr<ITEMIDLIST> pidl;
SHGetIDListFromObject(child, &pidl);
// the PIDL is absolute, we need the relative one (the last itemId in the list)
// get it's install location
CComVariant v;
if (SUCCEEDED(folder->GetDetailsEx(ILFindLastID(pidl), &pkLocation, &v)))
{
// it's a VT_BSTR
wprintf(L" %s\n", v.bstrVal);
}
}
Note it's using an undocumented System.Software.InstallLocation PROPERTYKEY. To find it I just dumped all columns with a code like this for each child:
int iCol = 0;
do
{
SHCOLUMNID colId;
if (FAILED(folder->MapColumnToSCID(iCol, &colId)))
break; // last column
CComHeapPtr<wchar_t> name;
PSGetNameFromPropertyKey(colId, &name);
CComVariant v;
if (SUCCEEDED(folder->GetDetailsEx(ILFindLastID(pidl), &colId, &v)))
{
if (v.vt == VT_BSTR)
{
wprintf(L" %s: %s\n", name, v.bstrVal);
}
else
{
wprintf(L" %s vt: %i\n", name, v.vt);
}
}
iCol++;
} while (true);
}
PS: I've not added much error checking, but you should.

Expression result unused in String Method

I created this method to remove only the white space from the end of a string and not the beginning, while it returns the string perfectly and does what I need, the xcode interface tells me "Expression result unused" in the "for (lengthofthestring ; lengthofthestring > 0; lengthofthestring--)" line, CAN ANYONE TELL MY WHY, BEFORE I TEAR ALL MY HAIR OUT!!! thanks.
But it runs fine, (I don't want any hassles from the store)
Heres the code...
-(NSString *)removeEndSpaceFrom:(NSString *)strtoremove{
NSUInteger location = 0;
NSUInteger lengthofthestring = [strtoremove length];
unichar charBuffer[lengthofthestring];
[strtoremove getCharacters:charBuffer];
////////////// right here on the next line is where i'm getting the Expression result unused !!!
for (lengthofthestring ; lengthofthestring > 0; lengthofthestring--) {
if (![[NSCharacterSet whitespaceCharacterSet] characterIsMember:charBuffer[lengthofthestring - 1]]){
break;
}
}
return [strtoremove substringWithRange:NSMakeRange(location, lengthofthestring - location)];
}
Well I fixed it this way, but I still don't know the answer to the above.
-(NSString *)removeEndSpaceFrom:(NSString *)strtoremove{
NSUInteger location = 0;
unichar charBuffer[[strtoremove length]];
[strtoremove getCharacters:charBuffer];
int i = 0;
for ( i = [strtoremove length]; i >0; i--){
if (![[NSCharacterSet whitespaceCharacterSet] characterIsMember:charBuffer[i - 1]]){
break;
}
}
return [strtoremove substringWithRange:NSMakeRange(location, i - location)];
}

System.AccessViolationException while initializing an array

void BinaryTree::InitializeFromFile(string Filename){
ifstream inFile;
treenode* Freq[256];
inFile.open(Filename.c_str(), fstream::binary);
if(inFile.fail()){
cout<<"Error in opening file "<<Filename;
return;
}
for(int i=0;i<=255;i++){
Freq[i]->weight=0;
Freq[i]->data = '0'+i;
Freq[i]->LChild = NULL; Freq[i]->RChild=NULL; Freq[i]->Parent=NULL;
}
char c;
inFile.get(c);
while(!inFile.eof()){
Freq[c]->weight ++;
inFile.get(c);
}
}
I'm getting the Access Violation Exception in the for loop. Even when I comment out certain lines it'll give me an error on the next line in that loop.
Edit: Also is the line Freq[c]->weight ++; valid? Can I go to a specific part of the array based on the char value?
You seem to never initialize your Freq table. It contains random pointers. Dereferncing an uninitialized pointer leads to undefined behaviour.
You ought to add Freq[i] = new treenode before Freq[i]->weight=0;.

Resources