Си... не пойму что неправильно...
Пользователи, просматривающие топик: none
|
Зашли как: Guest
|
Имя |
Сообщение |
<< Старые топики Новые топики >> |
|
|
Си... не пойму что неправильно... - 2006-11-30 17:19:17.046666
|
|
|
VDShark
Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
|
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <alloc.h>
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<5;i++)
if(!print(&mas[i])) printf("\nElement %d ne zapolnen!",i+1);
for(i=0;i<5;i++)
Delete(&mas[i]);
for(i=0;i<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->name=(char*)calloc(strlen(s)+1,sizeof(char));
strcpy(pPerson->name,s);
printf("\nVvedite vozrast: ");
scanf("%d",&pPerson->age);
}
int print(person *pPerson)
{
if(pPerson->name&&pPerson->age)
{
printf("\nFamiliya: %s Vozrast: %d let",pPerson->name,pPerson->age);
return 1;
}
else return 0;
}
void Delete(person *pPerson)
{
free(pPerson->name);
pPerson->name=NULL;
}
Так вот, при вызове функции Delete() вылетает программа…. протрассировал ее - оказалось при освобождении памяти… free(pPerson->name); Так вот, кто может объяснить - почему? И как с этим бороться?[&:]
|
|
|
RE: Си... не пойму что неправильно... - 2006-11-30 17:28:28.610000
|
|
|
__Andy__
Сообщений: 86
Оценки: 0
Присоединился: 2006-11-29 13:01:54.263333
|
Ты пытаешься освободить чужую память… Вот ОС тебе и дает по рукам
|
|
|
RE: Си... не пойму что неправильно... - 2006-11-30 17:29:51.593333
|
|
|
VDShark
Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
|
В каком месте интерено она чужая? Я ее самолично выделял)
|
|
|
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<5;i++)
Delete(&mas[i]); // все работает нормально до 3-ей итерации.. Там все и валится
Короче, после декларации массива, выделением памяти даже не пахнет))))
|
|
|
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<5;i++) Delete(&mas); // все работает нормально до 3-ей итерации.. Там все и валится Нифига не работает, все валится на первой же итерации! В том то вся беда…. Так что дело походу не в этом.
|
|
|
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 ведь не более чем указатель…
|
|
|
RE: Си... не пойму что неправильно... - 2006-11-30 19:59:09.406666
|
|
|
VDShark
Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
|
Для mas[2].name память выделяется динамически…. смотри функцию input()…. и соответственно он же заполняется (после выделения)…. соответственно и указывает на какую то область памяти из части HEAP(область динамически выделяемой памяти). Люди, я не пойму - что, никто тут не разбирается что ли?[&:]
|
|
|
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.
|
|
|
RE: Си... не пойму что неправильно... - 2006-11-30 20:40:33.860000
|
|
|
VDShark
Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
|
Да я то это понимаю. Просто это задание из лабы, там строго оговорен ход построения программы. По другому не сделаешь… я впринципе нашел из за чего вылетает, но если исправлять - отклонение от постановки задачи :) Завтра пойду наверное ругаться, кто ток эти лабы составляет… Если не найду, как эту бадягу обойти, не выходя "за рамки" )
|
|
|
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 сколько влезет.
|
|
|
RE: Си... не пойму что неправильно... - 2006-11-30 20:51:50.936666
|
|
|
VDShark
Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
|
Да, я про это и говорил :) Так я делал, работает без б….. просто в рамках программы про strdup ничего не упоминалось, и хз - не прибадаются ли… Хотел все выполнить в рамках программы, а по условию первые 2 элемента инициализируются при объявлении. Ладно, оставлю с strdup'ом…. Всем спасибо за помощь) Спасибо что не остались безучастными)
|
|
|
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->name != petrov && p->name != ivanov)
free (p->name);
p->name = NULL; :) при желании, можно конечно попробовать научиться по адресу определять куда он указывает в кучу, в static или в стек, но портабельность такого кода будет равна нулю.
|
|
|
RE: Си... не пойму что неправильно... - 2006-11-30 21:09:03.656666
|
|
|
VDShark
Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
|
Да можно. При желании можно много чего придумать. Просто не хотелось бы стока лишних строк и операций сравнения в своем коде)
|
|
|
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 Вот, в чем проблема…
|
|
|
RE: Си... не пойму что неправильно... - 2006-12-01 10:24:58.170000
|
|
|
VDShark
Сообщений: 287
Оценки: 0
Присоединился: 2006-09-23 11:36:06.240000
|
Да не совсем в этом там проблема была… 8| Все - тема закрыта, ввиду неактуальности проблемы:)
|
|
|
|
|