简体   繁体   中英

Strcpy segfaults after Malloc

So, i was writing aa simple slice function in C, which takes an array of strings, the string that marks the beginning of the slice, and the size of the slice. in the function i malloc a new array, and then proceed to copy over each string in the slice to the new array. however, i get a segfault on the very first strcpy, even though i've already malloced space for the result array.

the code looks like this:

char** slice(char** args, char* start, int size){
  int i = 0;
  // need to find start first
  char* cursor = args[0];
  int j = 0;
  while(cursor != NULL){
    if(strcmp(cursor, start) == 0){
      break;
    }
    j++;
    cursor = args[j];
  }
  char** result = malloc(MAX_INPUT * size);
  while(i < size){
    strcpy(result[i], args[j+i]);
    i++;
  }
  return result;
}

the line which casues the segfault is --

strcpy(result[i], args[j+i]);

i've used gdb to peek into the values of whats in result and args, result[i] is 0x0, which is NULL, but result itself is an address but i'm not sure why malloc isn't working. have i run out of stack space? does this mean i'm screwed?

result[i] is an uninitialized pointer. You have made the same error as in:

char *ptr;
strcpy(ptr, args[j+i]);

You must make result[i] point to some allocated space before you can copy characters into it. Also, MAX_INPUT * size is the wrong amount of space to allocate for an array of pointers.

Another problem is that if size is bigger than the number of strings remaining in the array after start then you read off the end of the array.

Then your function never placs a NULL at the end of the new array, so the caller has no way of knowing how big the slice is that you have returned.

Also cursor is redundant, you could have just written args[j] . Basically the function is a complete mess.

The code could be (warning: untested):

char** slice(char** args, char const *start, int slice_size)
{
// Find index of "start"
    int start_index;

    for (start_index = 0; args[start_index]; ++start_index)
         if ( !strcmp(args[start_index], start) )
              break;

// Abort if "start" was not present (remove this line if you want to
// instead return an empty terminated list)
    if ( !args[start_index] )
         return NULL;

// Allocate array of pointers to new strings, allowing space for terminator
    char **result = malloc((slice_size + 1) * sizeof *result);
    if ( !result )
        return NULL;

// Copy strings in, allocating space for each string, stopping if no more args
    int i;
    for (i = 0; i < slice_size && args[start_index + i]; ++i)
         result[i] = strdup(args[start_index + i]);

// Terminate the list
    result[i] = NULL;

    return result;
}

this line:

char** result = malloc(MAX_INPUT * size);

mallocs MAX_INPUT characters times size. What is the meaning of the contents of 'size'.

Overall, what is needed is a malloc for a number of char * which I do not see in the code.

Then, after getting that malloc parameter correct,

The code needs to use strdup() rather than strcpy() -or- malloc room for each string and then use strcpy() , probably in a loop containing both function calls

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM