I'm trying to write a stream editor in C and I'm having a hard time dealing with strings. After reading in the lines of a File, I want to store them locally in an array of Strings. However, when I try to store the variable temp
into the array of strings StoredEdits
I get a segmentation fault (core dumped)
error. Furthermore, if I uncomment the char* temp2
variable and save this into my array as a workaround, then the last value read in gets stored for every value in the array.
I assume this has to do with the fact that temp2 is a pointer. I've tried a million things like malloc'ing and free'ing this variable after each iteration, but nothing seems to work.
Any help would be greatly appreciated.
#define MAX_SIZE 100
typedef char String[MAX_SIZE];
int main(int argc, char* argv[]){
char** StoredEdits;
int index, numOfEdits;
FILE *EditFile;
char* temp;
//char* temp2;
StoredEdits = (char**)malloc(MAX_INPUT_SIZE*sizeof(String));
/*Check to see that edit file is passed in.*/
if(argc < 2){
printf("ERROR: Edit File not given\n");
return(EXIT_FAILURE);
}
printf("%s\n",argv[1]);
if( (EditFile = fopen(argv[1],"r")) != NULL ){
printf("file opened\n");
numOfEdits = 0;
while(fgets(temp, MAX_STRING_SIZE, EditFile) != NULL){
printf("%d %s",numOfEdits,temp);
//temp2 = temp;
StoredEdits[numOfEdits++] = temp;
//StoredEdits[numOfEdits++] = temp;
printf("Stored successfully\n");
}
..........
printf("%d\n",numOfEdits);
for(index=0;index<numOfEdits;index++){
printf("%d %s\n",index, StoredEdits[index]);
}
You need to initialize temp to point to valid storage.
temp = malloc(MAX_STRING_SIZE+1);
It looks like you may have intended to do something like this:
String temp;
using your macro. This would be better as a regular char array. And the common name for this is buffer.
char buffer[MAX_STRING_SIZE+1];
Then, you should store in your array, not temp
itself, but a new string containing a copy of the contents. There is a POSIX function strdup
that should be helpful here. Note, strdup
is not part of the C standard, but it is available in most hosted implementations. Historically, it comes from the BSD branch.
StoredEdits[numOfEdits++] = strdup(temp);
Let me backpedal a little and say that if you're allocating new storage for temp
inside the loop, then you should skip the strdup
because, as Jim Balter says, this will leak memory. If you allocate temp
outside of the loop, then it makes little difference whether you allocate it statically (by declaring a char []
) or dynamically (with malloc
).
By the way, this line will not buy you much:
typedef char String[MAX_SIZE];
For why, see the classic Kernighan (the K in K&R) essay Why Pascal is not my favorite Programming Language.
Also note, that my examples above do not check the pointer returned by malloc
. malloc
can fail. When malloc
fails it will return a NULL pointer. If you try to store data through this pointer, Kaboom!