So I basically want my program to be able to save multiple (or in this case, just two) arguments into a string if the program is started with the option -a. Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
int main(int argc, char **argv) {
char c;
char *optstr;
int acount = 0;
while( (c = getopt(argc, argv, "a")) != -1) {
switch(c) {
case 'a': acount++; break;
case '?': fprintf(stderr, "wrong opt\n"); exit(1); break;
default: assert(0);
}
}
char *temp;
if(acount == 1) {
optstr = argv[optind];
temp = strdup(optstr);
if(optind+1 < argc) {
temp = realloc(temp, (strlen(temp) + 1 + sizeof(" ")));
temp = strcat(temp, " ");
temp = realloc(temp, (strlen(temp) + 1 + strlen(argv[optind+1])));
temp = strcat(temp, argv[optind+1]);
}
} else {
fprintf(stderr, "too many or not enough a's\n");
exit(1);
}
fprintf(stdout, "%s\n", temp);
return 0;
}
My question lies with the whole realloc business going on. I originally tried the whole thing without the temp variable, and I used optstr instead. Which only gave me "realloc(): invalid pointer" errors. I'm asking - why is that, and why does it suddenly work with temp? Is this because optstr's pointer is pointing at an argument in argv, and changing argv would cause errors? I'm really not sure at all.
It's because you don't know how the memory for the strings inside argv
are allocated. You are not supposed to know. They might have been created individually using malloc
, in which case realloc
will work (but it's not legal), or a large block was malloc
'd and the strings placed within the block, in which case it won't work, or some other variants.
When you call realloc
on a pointer from argv
you are claiming that you own that memory; this is not true and you are not allowed to reallocate or free it. See also Memory allocation and **argv argument
You are only allowed to read the memory, so what you can do, and have done, is use strdup
to create a copy; this memory you then do own, so now you are allowed to use realloc
on it.