Thread: Array pointer question

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    66

    Array pointer question

    Hi.

    I have a problem and I can`t figure out, how to solve it. Let`s say I have a pointer which holds the address of an array, and I allocate memory for 10 elements. Is there any possibility to verify if an element exists on a specified index?

    For example I have a dinamically alocated array, and I want to check if arr[2] exists.

    If I do this: if (arr[2] != NULL) it gives me segmentation fault, and I understand why, but can somebody tell me if exists another solution to this problem, or it can be done only by checking the size of the variable?

    Thank you

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You have to keep track of the length yourself. You either keep this in another variable and use it like so:
    Code:
    for( x = 0; x < LENGTH; x++ )
        ... do stuff with ptr[ x ] ...
    Or you copy what strings do, and you allocate one extra element and set aside one value of that type of variable to check to see if you have reached the end:
    Code:
    for( x = 0; array[ x ] != SECRETVALUE; x++ )
        ... do stuff with ptr[ x ] ...
    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    66
    Thank you for your answer.

    Why did I ask that... I have the following function which returns an array with the files from a folder. I modified that so now I can pass a pointer which will hold the length of the array. The function looks like this:

    Code:
    typedef struct
    {
    	char *fileName;
    	int isFile;
    } FileData;
    
    FileData **fs_listFiles(const char *path, int *length)
    {
    	DIR *dir;
    	struct dirent *ent;
    	FileData **fd;
    	int i;
    
    	dir = opendir (path);
    
    	if (dir != NULL)
    	{
    
    		while ((ent = readdir (dir)) != NULL)
    		{
    			fd 			= (FileData **)realloc((void *)fd, sizeof(FileData*)*(i+1));
    			fd[i]			= (FileData *)malloc(sizeof(FileData));
    			fd[i]->fileName = strdup(ent->d_name);
    
    			printf("%s\n",fd[i]->fileName); //here everything is ok
    
    			i++;
    			(*length)++;
    		}
    
    		closedir (dir);
    		return fd;
    	}
    
    	return NULL;
    }
    
    
    int main()
    {
    
    	int length = 0;
    	FileData **res = fs_listFiles("/home/user",&length);
    
    	printf("%d\n",length); //length is let`s say 53, ok...
    
    	return 0;
    }

    The problem is that doesn`t matter what value the length variable holds, if I print this to the screen: printf("%s\n",res[0]->fileName); it gives me segmentation fault. According to the length (which is let`s say 53, it should be an index 0 in the array);

    I`m sure is something wrong with the function itself, but i can`t figure out what, because if I printf the file name or the current index or anything else in the function, it is ok, but if I try to use the array returned from the function doesn`t matter what I do, it gives me segmentation fault.


    Thank you.

  4. #4
    Registered User TheBigH's Avatar
    Join Date
    May 2010
    Location
    Melbourne, Australia
    Posts
    426
    Does initializing your variable "i" to zero help at all?
    Code:
    while(!asleep) {
       sheep++;
    }

  5. #5
    Registered User
    Join Date
    May 2011
    Posts
    66
    Thank you very much TheBigH, I can`t believe I didn`t see that.

    No of course it works like a charm. Thank you again.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I believe TheBigH has discovered the source of your program, but a few other things that you may want to consider:
    • Do you really need the extra level of indirection? Instead of a FileDat.........., you could have used a FileData*.
    • Have you considered having a FileDat.......... parameter and then returning the length? This is in conjunction with removing one level of indirection, though you re-introduce it in order to change the pointer from the caller.
    • Instead of always reallocating in the loop, one technique is to keep track of both the number of elements in use and the capacity allocated, then expand the dynamic array when needed. You can always resize later if needed.
    • realloc and malloc may return a null pointer, so strictly speaking you should handle these error cases.
    • You should use free where appropriate.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Since we're all throwing out hints, if you turn up your compiler warnings, you can typically catch things like using variables uninitialized.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    May 2011
    Posts
    66
    Hi.

    laserlight: Thank you for the suggestions. I was thinking about refectoring this part later, for the moment I just wanted to see if it works.

    quzah: I didn`t turn off the compiler warnings, but as I remember there was no warning regarding to this, or maybe I just didn`t pay attention to it.

    Thank you all for the help, and have a nice day.

    Zoli

  9. #9
    Registered User
    Join Date
    May 2011
    Posts
    66
    I forgot one thing, maybe you can help me in that too.

    This part of code works just fine, but now I have another error, which is related to this function, and I can`t figure out what is the problem with it. I have a function called getList() which calls fs_listFiles().

    This is the function:


    Code:
    void getList(char *currentPath)
    {
    	char buffer[4096] 		= "\0"; // TODO: temporary
    	char *fullPath			= NULL;
    	size_t fullPathLength	= 0;
    	int i					= 0;
    	int length 				= 0;
    	FileData **res			= NULL;
    
    	if (currentPath != NULL)
    	{
    		fullPathLength = strlen(MEDIA_PATH) + strlen(currentPath)+1;
    
    		fullPath = malloc(fullPathLength);
    
    		if (fullPath != NULL)
    		{
    			bzero(fullPath,fullPathLength);
    			strcpy(fullPath,MEDIA_PATH);
    			strcat(fullPath,currentPath);
    		}
    
    		res	= fs_listFiles(fullPath, &length);
    	}
    	else
    	{
    		res	= fs_listFiles(MEDIA_PATH, &length);
    	}
    
    
    /* some implementation for res */
    
    free(fullPath);
    fullPath = NULL;
    
    free(res);
    res = NULL;
    
    }
    MEDIA_PATH is a macro which holds let`s say /home/user/music/


    The problem is the following:
    If I don`t have the if (currentPath != NULL) part, just pass the MEDIA_PATH to the fs_listFiles() function it works, but if I use the currentPath it gives me segfault (the weird thing is that it breaks in the another function at this line: fd = (FileData **)realloc((void *)fd, sizeof(FileData*)*(i+1)). I can think of any connection between the two things. I also tried to concatenate the NULL terminator to currentPath, i thought that maybe this is the problem, but it`s not. If I comment the lines where I call fs_listFiles() everything works just fine, and if I printf the currentPath or the fullPath variables they give me exactly what I expect. If the MEDIA_PATH is /home/user/music and the currentPath is some_album then the result is /home/user/music/some_album.

    I also tried to use gdb, and it says that there is an invalid pointer at some realloc, and it can be the realloc from the first function, but I cannot imagine what is the problem, because the two pieces of code work fine separately, but not together.


    Thank you.

    Zoli.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    All that means is that you're trashing memory, overwriting the value of fd at some point along the way. I can't really tell from your prose whether the code you've provided is the one with the error on realloc, or is the one with some other error.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pointer to an array question..
    By transgalactic2 in forum C Programming
    Replies: 41
    Last Post: 10-20-2008, 12:22 PM
  2. Pointer Array Question
    By d320 in forum C Programming
    Replies: 5
    Last Post: 07-11-2008, 11:51 PM
  3. pointer/array question
    By saller in forum C Programming
    Replies: 8
    Last Post: 01-10-2006, 09:39 PM
  4. Array/Pointer question
    By Swaine777 in forum C++ Programming
    Replies: 2
    Last Post: 05-17-2003, 10:29 PM
  5. A question between Array and Pointer
    By Unregistered in forum C++ Programming
    Replies: 16
    Last Post: 08-05-2002, 09:13 AM