View Full Version : دلایل تغییر یک متغیر
shaaadi
پنج شنبه 06 اسفند 1388, 22:57 عصر
این یکی از تابع های برنامه ی من هست :
product* add(FILE*fo,product* shead,int number)
{
product* newnode=new product[1];
char nameofcake[20];//baraye inke esmi ke az file mikhoonam ro inja berizam
for (int j=0;j<20;j++) // khoondan e esm az file
{
nameofcake[j]=fgetc(fo);
if (nameofcake[j]==' ')
{
nameofcake[j]='\0';
j=20;
}
}
int hard=fgetc(fo)-48; // khoondan darajeye sakhti (yek shomare )
int temp=fgetc(fo); // khoondane null va rikhtan dar yek chize alaki
int pnumber=fgetc(fo)-48;//khoondane shomareye marhale(yek shomare)
temp= fgetc(fo);// khoondane null
//struct product=new product;
newnode->level=hard;// sakhtan e node e jadid
//char*name=nameofcake;
char*name=nameofcake;
newnode->name=name;
newnode->next=0;
switch (pnumber)//taeeen kardan e noe tabe ya noe marhale ya farayandi ke bayad anjam beshe
{
case 1:
newnode->process=&makhloot;
break;
case 2:
newnode->process=&ghaleb;
break;
case 3:
newnode->process=&pokht;
break;
case 4:
newnode->process=&tazeen;
break;
default: printf("u r wrong");
}
product* node=new product[1];// marahele gozashtan e node dar akharin jaye momken
node=shead->next;
for (int k=0;k<number;k++)
node=node->next;
node=newnode;
shead->next=node;
return shead;
}
برای پیدا کردن مشکل هاش خط به خط اجرا کردم و دیدم که در قسمت :
for (int j=0;j<20;j++)
{
nameofcake[j]=fgetc(fo);
if (nameofcake[j]==' ')
{
nameofcake[j]='\0';
j=20;
}
}
در shead اون هم قسمت name تغییر ایجاد میشه ... یعنی هر بار که
nameofcake[j]=fgetc(fo)
همین کاراکتر گرفته شده به name هم میره ! در صورتی که اینجا اصلا ربطی به اون shead نداره ! چرا ؟
راستی shead هم به این صورته:
struct product
{
int level;
char* name;
int (*process)(int);
product*next;
}shead;
یعنی چه دلایلی میتونه داشته باشه که یک متغیر بی ربط تغییر کنه ؟
shaaadi
جمعه 07 اسفند 1388, 00:22 صبح
تابعی که تو پست قبل نوشته بودم رو حذف کردم و تو تابع اصلی نوشتم :
int main()
{
using namespace std;
product*head=new product[1];
head->next=0;
FILE* fo;
FILE* fe;
fe=fopen("end.txt","w");
fo=fopen("s.txt","r");
int lines = fgetc(fo)-48;
int temp = fgetc(fo);
product* node=new product[1];
//node=add(fo,head);
node=head->next=new product[1];
for(int i =0;i<lines;i++)
{
//product* newnode=new product[1];
char nameofcake[20];//baraye inke esmi ke az file mikhoonam ro inja berizam
for (int j=0;j<20;j++) // khoondan e esm az file
{
nameofcake[j]=fgetc(fo);
if (nameofcake[j]==' ')
{
nameofcake[j]='\0';
j=20;
}
}
int hard=fgetc(fo)-48; // khoondan darajeye sakhti (yek shomare )
int temp=fgetc(fo); // khoondane null va rikhtan dar yek chize alaki
int pnumber=fgetc(fo)-48;//khoondane shomareye marhale(yek shomare)
temp= fgetc(fo);// khoondane null
//struct product=new product;
node->level=hard;// sakhtan e node e jadid
//char*name=nameofcake;
node->name=nameofcake;
//node->next=0;
switch (pnumber)//taeeen kardan e noe tabe ya noe marhale ya farayandi ke bayad anjam beshe
{
case 1:
node->process=&makhloot;
break;
case 2:
node->process=&ghaleb;
break;
case 3:
node->process=&pokht;
break;
case 4:
node->process=&tazeen;
break;
default: printf("u r wrong");
}
node->next=node;
}
print(node,fe,lines);
return 0;
}
اما سر همون جای قبلی یعنی زمانی که یک رشته حرف رو از فایل می خونم همون اتفاق میفته ... یعنی تو متغیر نام node تغییر ایجاد میشه و به جای سه خط متفاوت ... سه خط عین هم چاپ میکنه !!!!:متعجب:
amin1softco
جمعه 07 اسفند 1388, 00:23 صبح
شاید مقداری که خونده میشه بیشتره از فضای تخصیص داده باشه و وقتی از اون فضا تجاوز کنه ممکنه با یک آدرس دیگه تداخل ایجاد بشه البته به نظر من شاید مشکل از جای دیگه باشه
shaaadi
جمعه 07 اسفند 1388, 00:31 صبح
اخه خیلی منظم هر سه تاشو عوض میکنه برای همین نمیشه بگیم اشکال از اونه !!! (البته شایدم بشه ! چون شما بهتر میدونی !)
#include<iostream>
#include<stdio.h>
struct product
{
int level;
char* name;
int (*process)(int);
product*next;
};
int ghaleb(int x)
{
int y=10+x;
return y ;
}
int tazeen(int x)
{
return x;
}
int pokht(int x)
{
int y = 15 + 10*x;
return y;
}
int makhloot(int x)
{
int y=2*x;
return y;
}
void print(product*head,FILE * fe,int n)
{
using namespace std;
product* tempnode=new product[50];
tempnode=head->next;
for(int j=0 ; j<n;j++)
{
if(tempnode->process==&makhloot)
{
cout<<tempnode->name<<" was mixed at "<<tempnode->process(tempnode->level)<<"\n";
fprintf(fe,"%s was mixed at %d\n",tempnode->name,tempnode->process(tempnode->level));
}
else if(tempnode->process==&ghaleb)
{
cout<<tempnode->name<<" was ghaleb giri! at "<<tempnode->process(tempnode->level)<<"\n";
fprintf(fe,"%s vas ghaleb giri ! at %d\n",tempnode->name,tempnode->process(tempnode->level));
}
else if(tempnode->process==&pokht)
{
cout<<tempnode->name<<" was baked at "<<tempnode->process(tempnode->level)<<"\n";
fprintf(fe,"%s vas was baked at %d\n",tempnode->name,tempnode->process(tempnode->level));
}
else if(tempnode->process==&tazeen)
{
cout<<tempnode->name<<" was tazeen! at "<<tempnode->process(tempnode->level)<<"\n";
fprintf(fe,"%s vas was tazeen! at %d\n",tempnode->name,tempnode->process(tempnode->level));
}
else
printf("u r wrong");
tempnode=tempnode->next;
}
}
int main()
{
using namespace std;
product*head=new product[1];
head->next=0;
FILE* fo;
FILE* fe;
fe=fopen("end.txt","w");
fo=fopen("s.txt","r");
int lines = fgetc(fo)-48;
int temp = fgetc(fo);
product* node=new product[1];
//node=add(fo,head);
node=head->next=new product[1];
for(int i =0;i<lines;i++)
{
//product* newnode=new product[1];
char nameofcake[20];//baraye inke esmi ke az file mikhoonam ro inja berizam
for (int j=0;j<20;j++) // khoondan e esm az file
{
nameofcake[j]=fgetc(fo);
if (nameofcake[j]==' ')
{
nameofcake[j]='\0';
j=20;
}
}
int hard=fgetc(fo)-48; // khoondan darajeye sakhti (yek shomare )
int temp=fgetc(fo); // khoondane null va rikhtan dar yek chize alaki
int pnumber=fgetc(fo)-48;//khoondane shomareye marhale(yek shomare)
temp= fgetc(fo);// khoondane null
//struct product=new product;
node->level=hard;// sakhtan e node e jadid
//char*name=nameofcake;
node->name=nameofcake;
//node->next=0;
switch (pnumber)//taeeen kardan e noe tabe ya noe marhale ya farayandi ke bayad anjam beshe
{
case 1:
node->process=&makhloot;
break;
case 2:
node->process=&ghaleb;
break;
case 3:
node->process=&pokht;
break;
case 4:
node->process=&tazeen;
break;
default: printf("u r wrong");
}
node->next=node;
}
print(node,fe,lines);
return 0;
}
این کله کد منه ! زیاد نیست ! جای خاص دیگه ای هم نداره ...:ناراحت: ممکنه که یک متغیر به متغیر دیگه ربط پیدا کنه ؟ (البته بدون &)
shaaadi
جمعه 07 اسفند 1388, 09:20 صبح
یک ذره که بیشتر دقت کردم ... دیدم وقتی میرسه به این خط :
newnode->name=nameofcake;
ادرس این دو تا رو با هم برابر قرار میده ! و از اون به بعد این دو تا با هم تغییر میکنن! اما چه طوری می تونم کاری بکنم که ارایه ی nameofcake به طور string تو newnode->name ذخیره بشه اما ادرسشون یکی نشه ؟
shaaadi
جمعه 07 اسفند 1388, 09:50 صبح
خیلیییییییی خیلییییییی ممنون که وقت گذاشتین !!!(فقط دکمه ی تشکر کافی نبود !)
#target
جمعه 07 اسفند 1388, 09:50 صبح
ادرس این دو تا رو با هم برابر قرار میده ! و از اون به بعد این دو تا با هم تغییر میکنن
وقتی دو char* را با هم قرار می دهید یعنی دو اشاره گر را با هم برابر قرار می دهید نه اینکه مقدار های آنها را پس هر تغییری که این در اطلاعات بده اون هم به دلیل اینکه به همون خانه از حافظه اشاره می کنه برابر میشه
با استفاده از کلمه کلیدی new می توانید فضای جدید از حافظه برای رشته ای که استفاده میکند در لیستتان ( و یا هر قسمت دیگر ) در نظر بگیرید و سپس کلیه کاراکتر های char* فعلی را تا رسیدن به عنصر NULL به عنصر name در لیستتان اضافه کنید
shaaadi
جمعه 07 اسفند 1388, 13:55 عصر
ببخشید فقط یک سوال از کدی که دادین :
شما داخل استراکچر رو عوض کردین یعنی :
struct product
{
int level;
char name[20];
int (*process)(int);
product*next;
};
و بعد از strcpy استفاده کردین ... نمیشه یک کاری کرد که به همون شکل :
char*name باقی بمونه ؟ میدونم که ارایه هم نوعی پوینتره اما اگه بخوایم همون صورت بمونه چه کار میشه کرد ؟
#target
جمعه 07 اسفند 1388, 14:04 عصر
اگر بخواهید از char* استفاده کنید و اونطور انتساب بدید فقط آدرس خانه ها کپی میشه . مگر اینکه برای هر بار با new یک آدرس جدید تخصیص بدهید و سپس تمام محتوی char* فعلی (تا مقدار )null را به آدرس جدید کپی کنید
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.