0

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.

MicroVirus
  • 5,324
  • 2
  • 28
  • 53
skulpt
  • 527
  • 2
  • 6
  • 25
  • What's the value of `argv[optind]` when you use it? – Andrew Henle Nov 08 '15 at 13:03
  • 2
    `sizeof(" ")`? Did you mean `strlen(" ")`? BTW, you haven't freed the allocated memory. – Spikatrix Nov 08 '15 at 13:10
  • Does it matter in this case? It does work just fine. And yeah, I know I didn't free my memory, but that's just an example. – skulpt Nov 08 '15 at 13:19
  • @skulpt It mostly matters if you decide you want a longer separator, for instance `" - "`, then the code suddenly starts crashing; the way it is written makes it seem like it works differently that it does. – MicroVirus Nov 08 '15 at 13:22

1 Answers1

0

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.

Community
  • 1
  • 1
MicroVirus
  • 5,324
  • 2
  • 28
  • 53