Сохранение памяти C на протяжении всей функции - PullRequest
1 голос
/ 27 октября 2010

Предполагая, что у меня есть фрагмент кода, похожий на этот:

SOMESTRUCTURE *info;
info = malloc(sizeof(SOMESTRUCTURE));

while(something...)
{
     info->mini[0] = malloc(sizeof(SOMESTRUCTURE *)); // It's a structure inside the same structure
     while(something...)
     {
           info->mini[x]->name = malloc(sizeof(char *)*strlen(name));
           printf("%s\n", info->mini[0]->name); // This prints out the correct value
     }
}

printf("%s\n", info->mini[0]->name); // But now the value is lost and is null

Как я могу заставить значение info-> mini [0] -> name применяться ко всей функции?

Ответы [ 4 ]

3 голосов
/ 27 октября 2010

Нет, это все еще должно быть доступно для вас.Единственный способ потерять значение было бы, если бы x было 0 на одной из итераций вашего цикла while или если вы выполняете malloc во внешнем цикле без входа во внутренний цикл - трудно сказать,это возможно, поскольку вы не указываете, что такое something в обоих случаях.

Это правда, что переменная, созданная в определенной области, исчезнет, ​​когда вы выйдете из этой области, но здесь это не так.Выделенная память переживет изменения объема.Указанный указатель на эту память может не совпадать с вашим указателем в этом случае (info все еще находится в области видимости при выходе из внешнего оператора while).

Я вижу еще одинпотенциальная проблема - ваш malloc(sizeof(char *) * strlen(name)), вероятно, должен быть malloc(strlen(name) + 1) (так как sizeof(char) всегда равен 1).Вероятно, это работает, потому что char * обычно будет больше, чем char, но, тем не менее, это неправильный способ сделать это.

Однако в вашем коде я не вижу нигде, где вы фактически устанавливаете info->mini[0]->name ко всему, так что я в растерянности относительно того, как оно может иметь правильное значение, если только оно каким-то образом не получает значение из предыдущего malloc (это возможно, поскольку сам malloc не требуетсячтобы очистить память, которую он вам дает).

Вы должны опубликовать свой действительный код или, желательно, самый маленький фрагмент кода, который обнаруживает проблему.

1 голос
/ 27 октября 2010

Я рекомендую вам использовать функцию g_strdup в glib, см. API - в glib вы найдете много полезных функций для обработки строк:

Так что в вашем случае дублировать строку name вы бы просто сделали ...

info->mini[x]->name = g_strdup(name);

Отредактировано Как прокомментировано ... вы можете использовать стандартный strdup , чтобы получить ту же функциональность:

info->mini[x]->name = strdup(name);

Конец издания

Делая это, info->mini[x]->name будет указывать на динамически выделенное пространство памяти, которое будет доступно за пределами вашей функции - если вы не освободите это.

Если вы не хотите использовать glib, тогда:

info->mini[x]->name = malloc(sizeof(char) * (strlen(name) + 1));
strcpy(info->mini[x]->name,name);

В этом случае имейте в виду, что значение malloc имеет значение sizeof(char), поскольку строка - это массив символов, отличных от char *, как у вас было раньше. +1 - сохранить последний символ для символа с нулевым символом в конце.

1 голос
/ 27 октября 2010

убедитесь, что х никогда не равен 0

0 голосов
/ 27 октября 2010

Я вижу, что вы выделяете info->mini[x]->name, и на следующей строке выведите его.

Между прочим, вы, кажется, фактически не помещаете какие-либо данные в ->name, поэтому я не понимаю, как они могут вывести правильное значение.

Ваше распределение ->name зависит от значения x в то время. Но вы никогда не показываете, что x объявляется или его значение устанавливается.

Пожалуйста, покажите нам информацию об объявлении и присвоениях x и о том, где данные фактически копируются в ->name.

...