2014-10-07 1 views
-3

я получаю следующее сообщение об ошибке:Почему malloc вызывает коррупцию памяти здесь?

*** Error in `./vice': malloc(): memory corruption: 0x08e77530 *** 
Aborted (core dumped) 

Соответствующий код:

open_result * 
open_file_1_svc(open_args *argp, struct svc_req *rqstp) 
{ 
    static open_result result; 
    int obtained_fd; 
    int just_read; 
    int total_read = 0; 
    int max_bytes_read = 1024; 
    char *ptr_file; 
    char *pathName = "MyFiles/"; // strlen = 8 
    int toReserve; 

    xdr_free((xdrproc_t)xdr_open_result, (char *)&result); 

    // Construct full name of the file (in "MyFiles") 
    toReserve = strlen(argp->fname) + strlen(pathName) + 1; // "\0" 
    char *fullName = malloc(toReserve*sizeof(char)); 
    fullName = strdup(pathName); 
    fullName = strcat(fullName, argp->fname); 

    // Call to open in POSIX 
    obtained_fd = open(fullName, argp->flags); 

    result.fd = obtained_fd; 

    /* If there was an error while reading, the error code will be sent, but not 
     the file (it might not even exist) */ 
    if (obtained_fd < 0) { 
     result.characters = ""; 
     result.number_characters = 0; 
    } 
    /* If the file opening was successful, 
     both the fd and the file will be sent */ 
    else { 
     char *file_just_read = malloc(max_bytes_read * sizeof(char)); // This is the problem 
     ptr_file = file_just_read; 

     /* Reading the file byte by byte */ 
     while((just_read = read(obtained_fd, ptr_file, max_bytes_read)) > 0) { 
      total_read += just_read; 
      file_just_read = realloc(file_just_read, (total_read+max_bytes_read) * sizeof(char)); 
      ptr_file = file_just_read + total_read; 
     } 
     result.characters = file_just_read; 
     result.number_characters = total_read; 
    } 
    return &result; 
} 

Позвольте мне объяснить, что делает код. Это сервер с именем «vice», который связывается со своими клиентами через RPC. Предполагается, что эта функция получит «open_args» и вернет «open_result». Они определены в файле "vice.x". Соответствующая часть этого файла:

struct open_args { 
    string fname<>; 
    int flags; 
}; 

struct open_result { 
    string characters<>; 
    int number_characters; 
    int fd; 
}; 

open_file_1_svc должен попытаться открыть файл с именем, заданным в argp-> имя_файла в MyFiles каталога. Если open успешно, open_file_1_svc попытается скопировать содержимое файла в result.characters, посылая копию содержимого файла клиенту таким образом. Число_характеры позволят мне узнать, есть ли между ними нулевые байты.

Ошибка, которую я получаю, появляется, когда я пытаюсь выделить некоторую память для части файла, который я собираюсь прочитать.

Я читал об этом типе ошибок, но я не понимаю, что случилось с этим конкретным случаем.

+4

'char * fullName = malloc (toReserve * sizeof (char)); fullName = strdup (pathName); fullName = strcat (fullName, argp-> fname); 'Сначала вы просачиваете память, тогда ваша strcat() записывается без выделенного размера. СОВЕТ: Ваш 'toReserve' вычисляется, но не используется. – joop

+2

Отладка 101: Вы можете выделить ошибку? Создайте полную исполняемую программу, которая надежно запускает наблюдаемую проблему, а затем сокращает биты логики до тех пор, пока вы не получите минимальный объем кода, в идеале просто «main()», используя пару жестко закодированных значений? Помните, что 'strdup' не является частью стандарта C, подумайте об использовании' strcpy' или 'memcpy' вместо – DevSolar

+0

или snprintf() для построения пути. –

ответ

4

malloc не «провоцирует» коррупцию; mallocобнаруживает it.

Эта ошибка говорит вам, что что-то нацарапало данные метаданных доmalloc был вызван (на этот раз); у вас, вероятно, есть переполнение буфера.

Оба звонка в этом коде перед записью в память, поэтому переполнение, скорее всего, происходит в другом месте. (Я не сделал тщательную проверку, что этого код является правильным, но после того, как-фактум здесь.)


Edit: я пропустил неявный malloc вызов внутри strdup. Это вызовет переполнение, поскольку дублируемая строка имеет меньшее распределение. Я думаю, вы имеете в виду strcpy, а не strdup.

+0

OP действительно использует 'strdup', потому что' strcpy' потребует 2 аргумента, которые должны быть переданы –

+0

Ну, очевидно, что 'strdup' не будет компилироваться с двумя параметрами. – ams