malloc делает странные вещи с адресами памяти

Я делаю сортировку ведра, сортируя указатели на узлы в связанный список с фиктивным заголовком. Пользователь вводит значения для узлов, а затем они сразу же помещаются в соответствующее ведро. Моя проблема возникает, когда я пытаюсь выделить память для второго узла (не включая фиктивный заголовок) для связанного списка.

Это код, используемый для добавления узлов в корзину, где var — это значение, которое сортируется, а current — вновь созданный узел для сортировки:

void bucketSort(int var, nodeptr current)
    if(!bucket[var])
    {
    buckets[var] = (nodeptr) malloc(sizeof(nodeptr));
    buckets[var]->next = current;
    bucketrear[var] = current;
    }
    else
    {
    bucketrear[var]->next = current;
    bucketrear[var] = current;
    }
}

Это упрощенная версия (меньше значений) кода, используемого для создания нового узла:

void addNode(int value)
{
    nodeptr newNode;

    newNode= (nodeptr) malloc(sizeof(nodeptr));

    newNode->value = value;
    newNode->next = NULL;


    bucketDrop(value, newNode);
} 

С помощью операторов трассировки я обнаружил, что до Malloc второго узла (с тем же значением, что и у первого) адрес ведра [значение] -> следующий был обычным адресом, но после этого адрес был 17. Это значение 17 подошел в каждом тесте, который я сделал.

Любая помощь или идеи были бы замечательными. Заранее спасибо.


person Thaotic    schedule 28.05.2013    source источник
comment
sizeof nodeptr? Вы имеете в виду sizeof node или sizeof *newNode?   -  person Zeta    schedule 28.05.2013
comment
Можете ли вы вставить свой sctruc, а?   -  person Maresh    schedule 28.05.2013
comment
Если у вас перезаписывается память, то сначала убедитесь, что вы не используете указатели на локальные переменные, которые вы сохраняете. Я также рекомендую такие инструменты, как Valgrind.   -  person Some programmer dude    schedule 28.05.2013
comment
Помимо ошибки, уже обнаруженной Зетами, в C (отличном от C++) вы не должны приводить возврат malloc, это может скрыть тонкие ошибки.   -  person Jens Gustedt    schedule 28.05.2013


Ответы (3)


Я думаю, что это одно из решений.

buckets[var] = (nodeptr) malloc(sizeof(*buckets[var]));

newNode= (nodeptr) malloc(sizeof(*newNode));
person HS Song    schedule 28.05.2013
comment
Спасибо, это исправило. Я использовал malloc, который мне давали на лекциях, и мой наставник заверил меня, что это правильно. - person Thaotic; 29.05.2013

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

Поскольку вы приводите результат malloc к типу nodeptr, это означает, что это указатель (поскольку malloc() возвращает указатель), что также означает, что вы выделяете память размером с указатель.

Итак, учитывая, что вы назвали свою структуру nodestruct, чтобы выделить достаточно памяти, которую вы написали бы

newNode = (nodeptr) malloc(sizeof(struct nodestruct));
person grasbueschel    schedule 28.05.2013
comment
Пожалуйста, не переводите возвращаемое значение malloc() в C. И я думаю, что использование sizeof *newNode будет менее подвержено ошибкам, чем sizeof(struct nodestruct), но я думаю, это можно оспорить. - person Remi Gacogne; 28.05.2013
comment
@RemiGacogne, почему бы вам не указать возвращаемое значение malloc? Если вы не хотите использовать только void* в своем коде, вам все равно придется в какой-то момент выполнить приведение?! - person grasbueschel; 29.05.2013
comment
Начиная с ANSI C, указатель void может быть безопасно назначен любому типу указателя без необходимости приведения типов. Так что это больше не нужно, и поскольку каждое приведение может помешать компилятору предупредить вас об ошибке позже, его не следует использовать. - person Remi Gacogne; 29.05.2013

Следующее должно решить вашу проблему:

newNode= (nodeptr) malloc(sizeof(*nodeptr));

Причина в том, что nodeptr выглядит как указатель на структуру, и, следовательно, вы должны выделять память для структуры, а не для указателя.

From, в следующий раз, пожалуйста, также вставляйте определения своих структур.

person cosmos    schedule 28.05.2013