結構體里面char型指針賦值的問題


先上段代碼:

#include<stdio.h>
#include<stdlib.h>

typedef struct
{
int id;
char *name;
}elem;

typedef struct
{
elem *EE;
int length;
}Sqlist;

Sqlist a;

int  InitList_Sq(Sqlist *L)    //構造
{
L->EE=(elem *)malloc(10*sizeof(elem));
L->length = 0;
return 1;
}

int ListInsert_Sq(Sqlist *L, elem e)    //末端插入
{
elem *q;
q = &(L->EE[L->length]); 
*q=e;
++L->length;
return 1;
}

void input()
{
elem temp;
char ch[21];
// temp=(elem *)malloc(sizeof(elem));
printf("請輸入id\n");
scanf("%d",&temp.id);
printf("請輸入name\n");
scanf("%s",ch);
temp.name=ch;
ListInsert_Sq(&a,temp);


}
void main()
{
InitList_Sq(&a);

input( );

printf("%d,%s",a.EE->id,a.EE->name);
}





我的意圖是:
Sqlist a; 
然后初始化a————InitList_Sq(&a);
接着,往a里面插入一個elem型結構體。
於是,有了:input( );  這個函數。
這個時候,問題就來了。

input( );函數里面,
只能正確輸出a.EE->id
但是,a.EE->name的值,要么就是輸出亂碼,要么就是直接程序崩潰。

調了好久一直找不到錯誤在哪里。
后來,在論壇找了下相關的,得出的結論是:沒有給temp分配空間。

因為沒有開辟一個elem型的temp的空間。
所以,賦值會出問題。
那么我就malloc一個咯。
這個時候,又出問題了。
但是,我用malloc的時候,一直有問題。
請問下,要怎么修改!
感激不盡了。(做一個課題,就卡在這個地方了)

11 个解决方案

#1



*q=e;
改為
q->id = e.id;
q->name = (char *)malloc(21);
strcpy(q->name,e.name);

#2



*q=e;
改為
q->id = e.id;
q->name = (char *)malloc(21);
strcpy(q->name,e.name);

#3


引用 2 樓 goodname 的回復:
將 
*q=e; 
改為 
q->id = e.id; 
q->name = (char *)malloc(21); 
strcpy(q->name,e.name); 


因為你的char *name沒分配內存的,所以出問題 

#4


瀏覽器出問題了,不小心恢復了2次。

你的程序的問題在於
*q=e的時候,對於char*成員是將指針賦值,注意到temp的name指向的是input()函數里面的局部變量ch,所以你的
Sqlist a的元素也指向了這個局部變量,但是當調用結束后該值就無效了。
所以你應該給你的elem的name開辟出適當的空間,並將內容拷貝進去。
你可以根據ch最大為21字節,也可以通過strlen(e.name)+1,通過用戶輸入的具體長度來開辟空間。

#5


typedef struct
{
    int id;
    char *name;   //再一次看到這種結構,既然你自己選擇的就必須2次malloc,一次malloc elem,一次q->name=(char*)malloc(5);    
}elem;


或者改成

typedef struct
{
    int id;
    char name[5];
}elem;

省事



#6


引用 1 樓 goodname 的回復:
將 
*q=e; 
改為 
q->id = e.id; 
q->name = (char *)malloc(21); 
strcpy(q->name,e.name);


正解!幫頂!

#7


引用 5 樓 hairetz 的回復:
typedef struct 

    int id; 
    char *name;  //再一次看到這種結構,既然你自己選擇的就必須2次malloc,一次malloc elem,一次q->name=(char*)malloc(5);    
}elem; 


嗯,按理說,是要malloc elem ,
但是,按照goodname的回復,直接在ListInsert_Sq函數里面,改寫。就可以了。我運行也沒有錯誤。
這也沒有malloc elem。

按照goodname的說法,也就是:temp.name指向了局部變量ch,然后在ListInsert_Sq函數里面,修改下,開辟個空間,這樣就行了。
也就可以少malloc一次了。

是不是這樣?

#8


2次malloc意思是說,
typedef struct
{
    int id;
    char *name;//因為這里還是個指針所以,對於每個元素都仍然要malloc一次。所以這里你可以改為char name[21];一個數組。到時候
//直接拷貝內容到字符數組,就可以減少一次malloc
}elem;

typedef struct
{
    elem *EE;//這里是個結構體指針,你一次malloc了10個元素。
    int length;
}Sqlist;

#9


引用 5 樓 hairetz 的回復:
typedef struct 

    int id; 
    char name[5]; 
}elem; 

省事 


嗯,沒錯,這種方式是省事,但是,如果我要把一個
char[21]="abcd"
賦值給elem.name
這個時候,就要一個一個賦值。有點麻煩。所以,我選用了*

#10


建議樓主看一下goodname的回復,寫的很好,還補充了解釋。

#11


引用 9 樓 cengkis 的回復:
引用 5 樓 hairetz 的回復:


typedef struct 

    int id; 
    char name[5]; 
}elem; 

省事 

嗯,沒錯,這種方式是省事,但是,如果我要把一個 
char[21]="abcd" 
賦值給elem.name 
這個時候,就要一個一個賦值。有點麻煩。所以,我選用了*

你用指針一樣的麻煩,首先你要為指針分配內存,而且你還必須用strcpy拷貝進去.否則,你將另外一個指針賦給他時,就會導致name和另外的一個指針指向同一個對象.你就很難保證其他地方是否對這個對象做修改或者銷毀.


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com