Добро пожаловать! Это — архивная версия форумов на «Хакер.Ru». Она работает в режиме read-only.
 

Си... не пойму что неправильно...

Пользователи, просматривающие топик: none

Зашли как: Guest
Все форумы >> [Компилируемые языки] >> Си... не пойму что неправильно...
Имя
Сообщение << Старые топики   Новые топики >>
Си... не пойму что неправильно... - 2006-11-30 17:19:17.046666   
VDShark

Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;string.h&gt; #include &lt;alloc.h&gt; typedef struct{ char *name; int age; } person; void input(person*); int print(person*); void Delete(person*); void main(void) { person mas[5]={{"Ivanov",18},{"Petrov",20}}; int i; input(&mas[2]); for(i=0;i&lt;5;i++) if(!print(&mas[i])) printf("\nElement %d ne zapolnen!",i+1); for(i=0;i&lt;5;i++) Delete(&mas[i]); for(i=0;i&lt;5;i++) if(!print(&mas[i])) printf("\nElement %d ne zapolnen!",i+1); getch(); } void input(person *pPerson) { char s[20]; printf("Vvedite Familiyu: "); gets(s); pPerson-&gt;name=(char*)calloc(strlen(s)+1,sizeof(char)); strcpy(pPerson-&gt;name,s); printf("\nVvedite vozrast: "); scanf("%d",&pPerson-&gt;age); } int print(person *pPerson) { if(pPerson-&gt;name&&pPerson-&gt;age) { printf("\nFamiliya: %s Vozrast: %d let",pPerson-&gt;name,pPerson-&gt;age); return 1; } else return 0; } void Delete(person *pPerson) { free(pPerson-&gt;name); pPerson-&gt;name=NULL; }
Так вот, при вызове функции Delete() вылетает программа…. протрассировал ее - оказалось при освобождении памяти…
free(pPerson->name);
Так вот, кто может объяснить - почему? И как с этим бороться?[&:]
Post #: 1
RE: Си... не пойму что неправильно... - 2006-11-30 17:28:28.610000   
__Andy__

Сообщений: 86
Оценки: 0
Присоединился: 2006-11-29 13:01:54.263333
Ты пытаешься освободить чужую память…
Вот ОС тебе и дает по рукам
Post #: 2
RE: Си... не пойму что неправильно... - 2006-11-30 17:29:51.593333   
VDShark

Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
В каком месте интерено она чужая? Я ее самолично выделял)
Post #: 3
RE: Си... не пойму что неправильно... - 2006-11-30 18:35:53.673333   
__Andy__

Сообщений: 86
Оценки: 0
Присоединился: 2006-11-29 13:01:54.263333
person mas[5]={{"Ivanov",18},{"Petrov",20}}; - тут выделена память для 2-х элементов…
И все…

Дальше ты пишешь: input(&mas[2]); //mas[2] - это 3-й элемент... память под него не выделена В с++ прога должна была упасть уже тут… =)))
Вместо этого, она берет какие-то данные, находятся в следующих sizeof(person) байтах от mas[1]… и пишет туда что-то…

for(i=0;i&lt;5;i++) Delete(&mas[i]); // все работает нормально до 3-ей итерации.. Там все и валится
Короче, после декларации массива, выделением памяти даже не пахнет))))
Post #: 4
RE: Си... не пойму что неправильно... - 2006-11-30 18:45:11.593333   
VDShark

Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
quote:

person mas[5]={{"Ivanov",18},{"Petrov",20}};
- тут выделена память для 2-х элементов…
И все…


Смотри внимательнее - память выделена вообще то под 5 элементов…. явно инициализировано 2.

quote:

Дальше ты пишешь:
input(&mas[2]); //mas[2] - это 3-й элемент… память под него не выделена


Соответственно, опять таки выделено….

quote:

В с++ прога должна была упасть уже тут… =)))
Вместо этого, она берет какие-то данные, находятся в следующих sizeof(person) байтах от mas[1]… и пишет туда что-то…

for(i=0;i&lt;5;i++)
Delete(&mas); // все работает нормально до 3-ей итерации.. Там все и валится


Нифига не работает, все валится на первой же итерации! В том то вся беда….

Так что дело походу не в этом.
Post #: 5
RE: Си... не пойму что неправильно... - 2006-11-30 19:50:03.610000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
quote:

ORIGINAL: VDShark

quote:

person mas[5]={{"Ivanov",18},{"Petrov",20}};
- тут выделена память для 2-х элементов…
И все…


Смотри внимательнее - память выделена вообще то под 5 элементов…. явно инициализировано 2.

ну да под пять. Но
1) выделена эта память из стека, а не из кучи.
2) free ты вызываешь не на эту память (что, между прочим, тоже привело бы к Segmentaton fault), а на хз что. вот объясни мне, что за адрес лежит, например, в mas[2].name. что там за значение? в какую область памяти ты читаешь строку, и какую область памяти ты потом пытаешься освободить? а name ведь не более чем указатель…
Post #: 6
RE: Си... не пойму что неправильно... - 2006-11-30 19:59:09.406666   
VDShark

Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
Для mas[2].name память выделяется динамически…. смотри функцию input()…. и соответственно он же заполняется (после выделения)…. соответственно и указывает на какую то область памяти из части HEAP(область динамически выделяемой памяти). Люди, я не пойму - что, никто тут не разбирается что ли?[&:]
Post #: 7
RE: Си... не пойму что неправильно... - 2006-11-30 20:31:51.046666   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
quote:

ORIGINAL: VDShark

Для mas[2].name память выделяется динамически….

ааа, да. стопудофф. сорри, проглядел. тогда глянь на *mas[0].name, и скажи мне где и как ты выделяешь память под него. ДУМАЙ! и думай над тем, почему выделяя память под него из стека (или статически, хз как там компилер делает), ты освобождаешь его функцией free.
Post #: 8
RE: Си... не пойму что неправильно... - 2006-11-30 20:40:33.860000   
VDShark

Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
Да я то это понимаю. Просто это задание из лабы, там строго оговорен ход построения программы. По другому не сделаешь… я впринципе нашел из за чего вылетает, но если исправлять - отклонение от постановки задачи :) Завтра пойду наверное ругаться, кто ток эти лабы составляет… Если не найду, как эту бадягу обойти, не выходя "за рамки" )
Post #: 9
RE: Си... не пойму что неправильно... - 2006-11-30 20:45:16.330000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
инициализируй первые два элемента массива ручками:
mas[0].name = strdup ("Ivanov"); mas[1].name = strdup ("Petrov"); если компилер умеет, то можно написать так:
person mas[5]={{strdup("Ivanov"),18},{strdup("Petrov"),20}}; после этого можно удалять через free сколько влезет.
Post #: 10
RE: Си... не пойму что неправильно... - 2006-11-30 20:51:50.936666   
VDShark

Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
Да, я про это и говорил :) Так я делал, работает без б….. просто в рамках программы про strdup ничего не упоминалось, и хз - не прибадаются ли… Хотел все выполнить в рамках программы, а по условию первые 2 элемента инициализируются при объявлении. Ладно, оставлю с strdup'ом…. Всем спасибо за помощь) Спасибо что не остались безучастными)
Post #: 11
RE: Си... не пойму что неправильно... - 2006-11-30 21:05:45.640000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
нну, тогда сделай так:
на глобальном уровне:
const char *petrov = "Petrov"; const char *ivanov = "Ivanov"; и удаляй так:
if (p-&gt;name != petrov && p-&gt;name != ivanov) free (p-&gt;name); p-&gt;name = NULL; :)
при желании, можно конечно попробовать научиться по адресу определять куда он указывает в кучу, в static или в стек, но портабельность такого кода будет равна нулю.
Post #: 12
RE: Си... не пойму что неправильно... - 2006-11-30 21:09:03.656666   
VDShark

Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
Да можно. При желании можно много чего придумать. Просто не хотелось бы стока лишних строк и операций сравнения в своем коде)
Post #: 13
RE: Си... не пойму что неправильно... - 2006-12-01 00:15:01.156666   
__Andy__

Сообщений: 86
Оценки: 0
Присоединился: 2006-11-29 13:01:54.263333
вот, что мне дебагер сказал:
+        [3]    {name=0x00000000 <Bad Ptr> age=0 }    person
+        [4]    {name=0x00000000 <Bad Ptr> age=0 }    person

Вот, в чем проблема…
Post #: 14
RE: Си... не пойму что неправильно... - 2006-12-01 10:24:58.170000   
VDShark

Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
Да не совсем в этом там проблема была… 8| Все - тема закрыта, ввиду неактуальности проблемы:)
Post #: 15
Страниц:  [1]
Все форумы >> [Компилируемые языки] >> Си... не пойму что неправильно...







Связаться:
Вопросы по сайту / xakep@glc.ru

Предупреждение: использование полученных знаний в противозаконных целях преследуется по закону.