My program runs without error but when I want to free 2D char array (like arguments[0]) it gives me : free(): invalid pointer, fish: Job 1, './a.out' terminated by signal SIGABRT (Abort)
/**
* @brief Parses the input into arguments
*
* EXP:
* "head -n 5 foo.txt"
* arguments[0] = "head"
* arguments[1] = "-n"
* arguments[2] = "5"
* arguments[3] = "foo.txt"
* arguments[4] = NULL
*
* @param input
* @return char**
*/
char** getArguments(char* input, int numOfArgs) {
char copy_arguments[BUFSIZ]; /* To parse input */
strcpy(copy_arguments, input);
char** arguments = calloc(numOfArgs 1, sizeof(char*));
if (arguments == NULL) {
return NULL;
}
/*allocate memory for arguments depending their length*/
char* argument = NULL;
for (int i = 0; i < numOfArgs; i ) {
if (i == 0) {
argument = strtok(copy_arguments, " ");
} else {
argument = strtok(NULL, " ");
}
int size_of_arg = strlen(argument);
arguments[i] = calloc((size_of_arg 1), sizeof(char));
strcpy(arguments[i], argument);
}
arguments[numOfArgs 1] = NULL;
return arguments;
}
int main() {
char **output = getArguments("hello world -n vim", 4);
free(output[0]);
}
CodePudding user response:
The function invokes undefined behavior. There are allocated numOfArgs 1
pointers
char** arguments = calloc(numOfArgs 1, sizeof(char*));
So the valid range of indices is [0, numOfArgs]
.
Thus in this statement
arguments[numOfArgs 1] = NULL;
there is an access to memory outside the allocated array.
Instead you have to write
arguments[numOfArgs] = NULL;
In general you should check that the returned pointer is not equal to NULL
as for example
if ( output ) free(output[0]);