Search code examples
cpointersmallocatoi

How to use atoi with an int and malloc?


When I try and use atoi with an int and malloc I get a bunch of errors and key is given the wrong value, what am I doing wrong?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct arguments {
    int key;
};

void argument_handler(int argc, char **argv, struct arguments *settings);

int main(int argc, char **argv) {
    argv[1] = 101; //makes testing faster
    struct arguments *settings = (struct arguments*)malloc(sizeof(struct arguments));
    argument_handler(argc, argv, settings);
    free(settings);
    return 0;
}

void argument_handler(int argc, char **argv, struct arguments *settings) {
    int *key = malloc(sizeof(argv[1]));
    *key = argv[1];
    settings->key = atoi(key);
    printf("%d\n", settings->key);
    free(key);
}

Solution

  • You probably want this:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct arguments {
      int key;
    };
    
    void argument_handler(int argc, char** argv, struct arguments* settings);
    
    int main(int argc, char** argv) {
      argv[1] = "101";  // 101 is a string, therefore you need ""
      struct arguments* settings = (struct arguments*)malloc(sizeof(struct arguments));
      argument_handler(argc, argv, settings);
      free(settings);
      return 0;
    }
    
    void argument_handler(int argc, char** argv, struct arguments* settings) {
      char* key = malloc(strlen(argv[1]) + 1);  // you want the length of the string here,
                                                // and you want char* here, not int*
    
      strcpy(key, argv[1]);                    // string needs to be copied
      settings->key = atoi(key);
      printf("%d\n", settings->key);
      free(key);
    }
    

    But this is very awkward, actually the argument_handler can be rewritten like this:

    void argument_handler(int argc, char** argv, struct arguments* settings) {
      settings->key = atoi(argv[1]);
      printf("%d\n", settings->key);
    }
    

    Disclaimer: I only corrected what was obviously wrong, there are still checks that need to be done, e.g. if argc is smaller than 2 etc.