LINUX.ORG.RU

[C] Освободить память занятую структурой.

 


0

1

Добрый день, ЛОР!

Столкнулся с такой проблемой:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <grp.h>

int main(void) {
gid_t gid=504;
struct group *gr=NULL;

if( (gr=getgrgid(gid)) == NULL)
perror(«GetGrGid »);
fprintf(stdout,«Name: %s\n»,gr->gr_name);
free(gr);
return 0;
}

struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* group members */
};

При попытке освободить память free(gr) получаю ошибку:
*** glibc detected *** ./gr: free(): invalid pointer: 0x0000003c59752700 ***

Подскажите нубу, что я делаю не так?


man getgrgid

RETURN VALUE

...

The return value may point to a static area which is overwritten by a subsequent call to getgrent(), getgrgid(), or getgrnam().

Попробуй юзать getgrgid_r

anonymous
()
Ответ на: комментарий от Eddy_Em

[C] Освободить память занятую структурой.

При попытке освобождать сначала поля структуры:
free(gr->gr_name);
free(gr->gr_passwd);
Та же история:
*** glibc detected *** ./gr: free(): invalid pointer: 0x0000000012d26016 ***

milton
() автор топика
Ответ на: [C] Освободить память занятую структурой. от milton

Бл*дь, ты ман то уже почитай по этой функции, что тебе указатель на структуру возвращает. Я тебе в первом посте уже процитировал, что далеко не факт, что там память вообще динамически аллоцируется, чтобы потом её free подсовывать.

anonymous
()
if( (gr=getgrgid(gid)) == NULL)
perror("GetGrGid ");
fprintf(stdout,"Name: %s\n",gr->gr_name);
free(gr);
return 0;
}

а можно вопрос? данная ветка кода выполняется только в том случае если у Вас (gr == NULL), то есть структура не создана, вот нафига её удалять?

и да, на будущее по code style, free() освобождает память, но не чистит значение указателя и он указывает, после free(), туда же куда и указывал, так что, хоть free() и проверяет на то что значение указателя не NULL, при попытке почистить второй раз будете получать ошибку

лучше пишите

free(gr);
gr = NULL;
shty ★★★★★
()
Ответ на: комментарий от shty

если у Вас (gr == NULL), то есть структура не создана, вот нафига её удалять?

Это он просто так код оформил красиво, под if там только perror стоит.

dmsh
()
Ответ на: комментарий от shty

и да, судя по отсутствию специализированной функции для удаления данной структуры, её чистка вообще не предполагается, то есть это просто набор указателей на внутренние структуры данных

shty ★★★★★
()
Ответ на: комментарий от anonymous

>>Бл*дь, ты ман то уже почитай по этой функции, что тебе указатель на структуру возвращает.
Бл*дь, спасибо, открыл глаза!

milton
() автор топика
Ответ на: комментарий от dmsh

если у Вас (gr == NULL), то есть структура не создана, вот нафига её удалять?

Это он просто так код оформил красиво, под if там только perror стоит.

от же блджад! с набегу подумал что опечатка, вообще я за такое по чайнику бил, виртуально конечно

shty ★★★★★
()
Ответ на: комментарий от rg-400

смотри внимательно

if( (gr=getgrgid(gid)) == NULL) { 
       perror("GetGrGid "); 
} 
 
fprintf(stdout,"Name: %s\n",gr->gr_name); 

в Вашем коде вижу, у ТС, согласитесь, несколько по-другому

вообще где-то видел определение качества кода, как количество «WTF???» отнесённое к количеству строк

shty ★★★★★
()
Ответ на: комментарий от shty

в Вашем коде вижу, у ТС, согласитесь, несколько по-другому

Вообще-то там тоже явно видно, просто нет отступов нормальных:

...
    if( (gr=getgrgid(gid)) == NULL)
        perror("GetGrGid ");
    fprintf(stdout,"Name: %s\n",gr->gr_name);
...
Так понятнее?

Eddy_Em ☆☆☆☆☆
()

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

rg-400
()
Ответ на: комментарий от rg-400

кстати, этот кусок кода - детский способ регулярно ломать себе ноги:

if( (gr=getgrgid(gid)) == NULL) { 
       perror("GetGrGid "); 
} 
 
fprintf(stdout,"Name: %s\n",gr->gr_name); 

потому что, даже если внезапно выяснится что структура NULL, то всё равно происходит обращение к её полям

shty ★★★★★
()
Ответ на: комментарий от rg-400

Точно, для автоматического exit'а нужно какой-нибудь err использовать.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Вообще-то там тоже явно видно, просто нет отступов нормальных:

вот как раз без отступов ничерта и не видно, и вообще, такой код:

    if( (gr=getgrgid(gid)) == NULL) 
        perror("GetGrGid "); 

это пример очень плохого code style, и является источником мириадов факапов (вот таких как у меня случился, к примеру :)

Так понятнее?

да мне уже всё давно понятно, ещё с тех пор как dmsh указал мне на это

shty ★★★★★
()
Ответ на: комментарий от shty

> при попытке почистить второй раз будете получать ошибку лучше пишите

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

ntp
()
Ответ на: комментарий от ntp

при попытке почистить второй раз будете получать ошибку лучше пишите

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

на то есть code review, а зануление указателей позволяет сократить количество мистических ошибок и время их вылавливания

shty ★★★★★
()

вообще RTFM.

у меня в мане написано

The return value may point to a static area, and may be overwritten by subsequent calls to getgrent(3), getgrgid(), or getgrnam(). (Do not pass the returned pointer to free(3).)

rha
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.