| | |
Dynamically allocating 2d arrays
Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved |
Basically I'm reading from a file and populating a dynamically allocated array with the words that are in the file. I've already read through the file to figure out what numArts is, so I know how many words there are in the array.
This works up until the:
if I remove those lines, the printf statment prints what I expect it to. I've tried doing this with pointer arithmetic as well. I just keep getting bus error over and over. From what I can tell and what I've been able to read about dynamically allocating arrays and such I'm doing this correctly. Does anyone see anything wrong with this?
This works up until the:
C Syntax (Toggle Plain Text)
arts[index] = (char*)malloc(strlen(word) * sizeof(char)); strcpy(*(arts + index), word);
if I remove those lines, the printf statment prints what I expect it to. I've tried doing this with pointer arithmetic as well. I just keep getting bus error over and over. From what I can tell and what I've been able to read about dynamically allocating arrays and such I'm doing this correctly. Does anyone see anything wrong with this?
C Syntax (Toggle Plain Text)
void populateArts(char **arts, FILE *fin, int *numArts) { int index; char* word; /* Temporary holding for each word */ arts = malloc(*numArts * sizeof(char*)); fscanf(fin, "%s", word); /* Skip over category */ /* Fill articles array */ for(index = 0; index < *numArts; index++) { fscanf(fin, "%s", word); printf("word is %s\n", word); arts[index] = (char*)malloc(strlen(word) * sizeof(char)); strcpy(*(arts + index), word); } }
>char* word; /* Temporary holding for each word */
>fscanf(fin, "%s", word);
Pointers aren't magic containers for infinite data. You need to allocate space to word before you can write to it. In this case, there's little point in using a pointer unless you want to get fancy with single character reads.
>arts[index] = (char*)malloc(strlen(word) * sizeof(char));
You cast the result of malloc in one call but not another. Consistency is more important than perfect style, but I'd still recommend removing the cast. Also, instead of
Finally, when allocating memory for a string, you need to add an extra slot for the null character. If you don't do that, you'll end up with problems later when overflowing the buffer.
Try this:
>fscanf(fin, "%s", word);
Pointers aren't magic containers for infinite data. You need to allocate space to word before you can write to it. In this case, there's little point in using a pointer unless you want to get fancy with single character reads.
>arts[index] = (char*)malloc(strlen(word) * sizeof(char));
You cast the result of malloc in one call but not another. Consistency is more important than perfect style, but I'd still recommend removing the cast. Also, instead of
sizeof(char) , you can get the same effect without specifying the type directly using sizeof *arts[index] . Also note that sizeof(char) is guaranteed to be 1.Finally, when allocating memory for a string, you need to add an extra slot for the null character. If you don't do that, you'll end up with problems later when overflowing the buffer.
Try this:
c Syntax (Toggle Plain Text)
void populateArts(char **arts, FILE *fin, int *numArts) { int index; char word[BUFSIZ]; /* Temporary holding for each word */ arts = malloc(*numArts * sizeof *arts); fscanf(fin, "%s", word); /* Skip over category */ /* Fill articles array */ for(index = 0; index < *numArts; index++) { fscanf(fin, "%s", word); printf("word is %s\n", word); arts[index] = malloc(strlen(word) + 1); strcpy(arts[index], word); } }
New members chased away this month: 5
Ah! I see. Fantastic. Thanks so much. I know pointers aren't "magic containers", but the only reason I was trying
is that earlier on while reading through the file I am doing this:
Which, to me, looked exactly the same as what I was doing in the other function, except for the allocating memory part, so I was getting confused as to why in countWords() I am able to read into a pointer that didn't have memory allocated to it and print out the correct results, but in populateArts() it wasn't working. Do you have some insight as to why it was working in one place, but not in another? I just would like to have the concept clarified, if you don't mind.
Thanks again!
Oh also, how do you specify what kind of syntax you are using with the CODE tags?
C Syntax (Toggle Plain Text)
char* word; fscanf(fin, "%s", word)
is that earlier on while reading through the file I am doing this:
C Syntax (Toggle Plain Text)
int countWords(FILE* fin) { int count = 0; char* temp; /* Temporary holding for each line */ fscanf(fin, "%s", temp); /* Read the category name, but don't count it */ while(*temp != '#' && !feof(fin)) { fscanf(fin, "%s", temp); printf("temp is %s\n", temp); if(*temp != '#') count++; } return count; }
Which, to me, looked exactly the same as what I was doing in the other function, except for the allocating memory part, so I was getting confused as to why in countWords() I am able to read into a pointer that didn't have memory allocated to it and print out the correct results, but in populateArts() it wasn't working. Do you have some insight as to why it was working in one place, but not in another? I just would like to have the concept clarified, if you don't mind.
Thanks again!
Oh also, how do you specify what kind of syntax you are using with the CODE tags?
•
•
•
•
Oh also, how do you specify what kind of syntax you are using with the CODE tags?
[CODE=C]
/*code goes here */
[/CODE]
also explained here
Last edited by niek_e; Nov 20th, 2008 at 11:39 am.
>Do you have some insight as to why it was working in one place, but not in another?
You got unlucky where it worked and lucky in another because bugs are more obvious when they break immediately. As for the detailed why, the random address as temp's value in countWords happened to be in your address space and writing to it happened not to cross any boundaries that would cause a segmentation fault. In populateArts, the random address wasn't nearly as benign.
>while(*temp != '#' && !feof(fin))
For future reference, feof isn't designed to be used as a loop condition like that. Because the end-of-file indicator for a stream is only set after you've tried and failed to read from the stream, loops constructed like this have an off-by-one error where the last record in the stream will be processed twice. This is easily tested and proven with a simple program:
You got unlucky where it worked and lucky in another because bugs are more obvious when they break immediately. As for the detailed why, the random address as temp's value in countWords happened to be in your address space and writing to it happened not to cross any boundaries that would cause a segmentation fault. In populateArts, the random address wasn't nearly as benign.
>while(*temp != '#' && !feof(fin))
For future reference, feof isn't designed to be used as a loop condition like that. Because the end-of-file indicator for a stream is only set after you've tried and failed to read from the stream, loops constructed like this have an off-by-one error where the last record in the stream will be processed twice. This is easily tested and proven with a simple program:
c Syntax (Toggle Plain Text)
#include <stdio.h> int main ( void ) { char buf[BUFSIZ] = "I'm a monkey! Ook ook!\n"; while ( !feof ( stdin ) ) { fgets( buf, sizeof buf, stdin ); printf ( "Processing a line: %s", buf ); } return 0; }
New members chased away this month: 5
![]() |
Similar Threads
- Macro for dynamically allocate multidimensional arrays (C)
- HEAP Corruption Error (C++)
- Error:Null Pointer assignment (C++)
- open a file and divide its data in arrays (C)
- help needed (C++)
- Sane way of dynamically allocating arrays beyond declaration. (C)
- C++ BASICS ==> Pointers, Call by Reference/Value, Inheritance, Functions & Arrays (C++)
- Pointers (C++)
Other Threads in the C Forum
- Previous Thread: corruption of the heap
- Next Thread: External Delaration for An Array?
Views: 1279 | Replies: 5
| Thread Tools | Search this Thread |
Tag cloud for C
adobe ansi api array arrays bash binarysearch centimeter char convert copyanyfile copypdffile cprogramme createcopyoffile createprocess() csyntax directory drawing dynamic executable fflush file fork frequency getlasterror givemetehcodez global graphics gtkgcurlcompiling hardware highest homework i/o inches infiniteloop initialization interest kilometer km lazy linked linkedlist linux linuxsegmentationfault list locate logical_drives match matrix meter microsoft motherboard multi mysql open opendocumentformat opensource owf pattern pdf performance pointer pointers posix power problem probleminc program programming pyramidusingturboccodes read recursion recv repetition scanf scheduling segmentationfault send shape socketprograming spoonfeeding stack standard strchr string strings structures student suggestions system systemcall test testautomation unix user voidmain() wab win32 win32api windows.h






