malloc(): повреждение памяти в странном месте

Я имел дело с раздражающей ошибкой повреждения памяти в течение нескольких часов. Я проверил все связанные темы здесь, и я не мог это исправить.

Прежде всего, я пишу простой терминал на C. Я разбираю команды между символами вертикальной черты (|) и перенаправления (>, ‹ и т. д.) и помещаю их в очередь. Ничего сложного!

Вот структура данных для очереди;

struct command_node {
    int index;
    char *next_symbol;
    struct command_node *nextCommand;
    int count;
    char **args;
};

Когда я сохраняю небольшие строки в указателе **args, все работает нормально. Однако, когда один из аргументов длинный, я получаю malloc(): ошибка повреждения памяти. Например, следующая 1-я команда работает нормально, 2-я команда вызывает ошибку

   1st:  ls -laF some_folder | wc -l

   2nd:  ls -laF /home/enesanbar/Application | wc -l

Я запускаю отладчик, он показал, что вызов malloc() для нового узла в очереди вызывает ошибку.

newPtr = malloc( sizeof(CommandNode) );

Я тщательно выделяю массив строк и освобождаю их после того, как закончу с ними, следующим образом:

    char **temp = NULL;
    temp = malloc(sizeof(char*) * number_of_args);

    /* loop through the argument array */
    for (i = 0; i < number_of_args; i++) {
        /* ignore the remaining commands after ampersand */
        if (strcmp(args[i], "&") == 0) return;

        /* split commands by the redirection or pipe symbol */
        if (!isSymbol(args[i])) {
            temp[count] = malloc(sizeof(strlen(args[i])) + 1);
            strcpy(temp[count], args[i]);
            count++;

            /* if it is the last argument, assign NULL to the symbol in the data structure */
            if (i + 1 == number_of_args) {
                insertIntoCommands(&headCommand, &tailCommand, temp, NULL, count);
                for (j = 0; j < count; j++) free(temp[j]);
                count = 0;  // reset the counter
            }

        }
        else {
            insertIntoCommands(&headCommand, &tailCommand, temp, args[i], count);
            for (j = 0; j < count; j++) free(temp[j]);
            count = 0;  // reset the counter
        }
    }

Должно быть, я что-то пропустил, или я чего-то не знаю о полях **args и размещении нового узла, хотя я ничего такого не делал раньше.


person enesanbar    schedule 28.11.2015    source источник
comment
temp[count] ‹-- что такое count?   -  person Andreas Grapentin    schedule 29.11.2015
comment
это нужно для того, чтобы отслеживать, куда поместить следующий аргумент, и я также сохраняю его для удобства при печати материала для отладки.   -  person enesanbar    schedule 29.11.2015
comment
sizeof(strlen(..., вероятно, не то, что вам нужно. уменьшите размер   -  person Art    schedule 29.11.2015
comment
Спасибо, это решило проблему, но как перенос числа вокруг sizeof может вызвать ошибку при выделении узла? Я просто пытаюсь понять из любопытства.   -  person enesanbar    schedule 29.11.2015
comment
Вы пытаетесь получить размер указателя внутри функции strlen, а не длину, которая предоставляется функцией.   -  person Michi    schedule 29.11.2015


Ответы (1)


но как может обернуть число вокруг sizeof, чтобы вызвать ошибку в выделении узла? Я просто пытаюсь понять из любопытства.

Как я уже говорил в своем комментарии, вы пытаетесь получить размер указателя внутри функции strlen, а не длину, которая предоставляется функцией.

Пожалуйста, взгляните на следующее:

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


int main(void){
    char *name = "Michi";
    size_t length1, length2;

    length1 = strlen(name);
    length2 =  sizeof strlen(name);

    printf("Length1 = %zu\n",length1);
    printf("Length2 = %zu\n",length2);
    return 0;
}

Выход:

Length1 = 5
Length2 = 8

И еще одно, после того, как вы free(temp[j]) не забудьте также free(temp).

Что-то вроде этого:

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


int main(void){
    long unsigned int size = 2,i;
    char **array;

    array = malloc(sizeof(char*) * size * size);

    if (array == NULL){
        printf("Error, Fix it!\n");
        exit(2);
    }

    for (i = 0; i < size; i++){
         array[i] = malloc(sizeof(char*) * 100);
    }

    /* do code here */

    for (i = 0; i < size; i++){
         free(array[i]);
    }
    free(array);

    return 0;
}
person Michi    schedule 28.11.2015