討論區快速選單
知識庫快速選單
網路投保旅行平安險 政府補助!學嵌入式+物聯網 傑米的攝影旅遊筆記
[ 回上頁 ] [ 討論區發言規則 ]
linklist的free問題
更改我的閱讀文章字型大小
作者 : frank007love(滴可明)
[ 貼文 65 | 人氣 9082 | 評價 20 | 評價/貼文 0.31 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/27 下午 10:57:36
//資料檔案
typedef struct File *FileLink;
typedef struct File
{
char *FileName;//檔案名稱
char *FileContent;//檔案內容
FileLink link;//檔案串列
};

//資料閘
typedef struct
{
char *FolderName;//資料閘名稱
FileLink Files;//資料檔案
}Folder;


//給檔案記憶體並且把名稱和內容存入
new_ptr=(FileLink)malloc(sizeof(FileLink));
new_ptr->FileName=(char*)malloc(sizeof(filename)+1);
strcpy(new_ptr->FileName,filename);
new_ptr->FileContent=(char*)malloc(sizeof(filecontent)+1);
strcpy(new_ptr->FileContent,filecontent);

//是放檔案記憶體
folder->Files=temp_ptr->link;
free(temp_ptr->FileName);
free(temp_ptr->FileContent);
temp_ptr->link=0;
free(temp_ptr);
作者 : frank007love(滴可明)
[ 貼文 65 | 人氣 9082 | 評價 20 | 評價/貼文 0.31 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/27 下午 10:59:06
忘了打問題上去:

就是在最後的free會當掉
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 上午 01:05:48
>//給檔案記憶體並且把名稱和內容存入
>new_ptr=(FileLink)malloc(sizeof(FileLink));

C 不需要 typecast.


>new_ptr->FileName=(char*)malloc(sizeof(filename)+1);

'filename' 是什麼?


>strcpy(new_ptr->FileName,filename);
>new_ptr->FileContent=(char*)malloc(sizeof(filecontent)+1);

'filecontent' 是什麼?


>strcpy(new_ptr->FileContent,filecontent);
>
>//是放檔案記憶體
>folder->Files=temp_ptr->link;
>free(temp_ptr->FileName);
>free(temp_ptr->FileContent);
>temp_ptr->link=0;
>free(temp_ptr);

可能你的指標或指向的記憶體已經 corrupted 了. 貼完整的程式碼, 否則無法知道問題在那裡.

作者 : frank007love(滴可明)
[ 貼文 65 | 人氣 9082 | 評價 20 | 評價/貼文 0.31 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 上午 10:20:12
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//資料檔案
typedef struct File *FileLink;
typedef struct File
{
char *FileName;//檔案名稱
char *FileContent;//檔案內容
FileLink link;//檔案串列
};

//資料閘
typedef struct
{
char *FolderName;//資料閘名稱
FileLink Files;//資料檔案
}Folder;

//建立一個新的資料閘
void CreateFolder(Folder *folder,char *foldername)
{
folder->FolderName=(char*)malloc(sizeof(strlen(foldername))+1);//給資料閘名稱記憶體
strcpy(folder->FolderName,foldername);//把檔案名稱複製給資料閘
folder->Files=0;
}

//增加一個資料閘檔案
void AddFile(Folder *folder)
{
//檔案名稱和檔案內容
char filename[20],filecontent[256];
//新增的檔案節點
FileLink new_ptr;

//輸入檔案名稱和內容
printf("請輸入檔案名稱: ");
scanf("\n%s",filename);
printf("請輸入檔案內容: ");
scanf("\n%s",filecontent);

//給檔案記憶體並且把名稱和內容存入
new_ptr=(FileLink)malloc(sizeof(FileLink));
new_ptr->FileName=(char*)malloc(sizeof(filename)+1);
strcpy(new_ptr->FileName,filename);
new_ptr->FileContent=(char*)malloc(sizeof(filecontent)+1);
strcpy(new_ptr->FileContent,filecontent);

//把檔案放入檔案閘串列
if(folder->Files==0)//檔案閘無資料-直接放
{
new_ptr->link=0;
folder->Files=new_ptr;
}
else//檔案閘有資料-放在頭
{
new_ptr->link=folder->Files;
folder->Files=new_ptr;
}
}

//印出輸入檔案名稱的內容
void DisplayFileContent(const Folder *folder)
{
//檔案名稱
char filename[20];
//所要的檔案
FileLink temp_ptr;

//輸入檔案名稱
printf("請輸入檔案名稱: ");
scanf("\n%s",filename);

//從頭開始找尋所要的檔案名稱
for(temp_ptr=folder->Files;temp_ptr!=NULL;temp_ptr=temp_ptr->link)
{
//看檔案名稱是否和要求相同
if(!strcmp(temp_ptr->FileName,filename))
{
printf("檔案內容: ");
printf("%s\n",temp_ptr->FileContent);
break;
}
}

//沒有搜尋到
if(!temp_ptr)
printf("沒有您要的檔案!!\n");
}

//印出檔案閘所有檔案名稱
void DisplayAllFiles(const Folder *folder)
{
//正在處理的檔案
FileLink temp_ptr;

printf("%s/\n",folder->FolderName);//檔案夾名稱

//印出檔案名稱
for(temp_ptr=folder->Files;temp_ptr!=NULL;temp_ptr=temp_ptr->link)
printf(" %s\n",temp_ptr->FileName);
}

//釋放所有用到的記憶體
void FreeAll(Folder *folder)
{
//正在處理的檔案
FileLink temp_ptr;

for(temp_ptr=folder->Files;temp_ptr!=NULL;temp_ptr=folder->Files)
{
folder->Files=temp_ptr->link;
free(temp_ptr->FileName);
free(temp_ptr->FileContent);
temp_ptr->link=0;
free(temp_ptr);
}
}

void main()
{
Folder root;//資料閘
char select='0';//動作選擇

//建立一個名稱為root的資料閘
CreateFolder(&root,"root");

while(select!='4')
{
//動作選擇
printf("---\n目前資料閘:/%s/\n請選擇下列操作命令:\n1: 增加一檔案\n"
"2: 列印檔案內容\n3: 列印目前資料匣內檔案\n4: 結束操作\n",root.FolderName);
scanf("\n%c",&select);

switch(select)
{
case '1'://增加一檔案
AddFile(&root);
break;
case '2'://列印檔案內容
DisplayFileContent(&root);
break;
case '3'://列印目前資料匣內檔案
DisplayAllFiles(&root);
break;
case '4'://結束操作
FreeAll(&root);
break;
default://輸入錯誤就重新輸入
printf("請重新輸入選擇!!\n");
break;
}

}

}
作者 : slchang(SL)
[ 貼文 117 | 人氣 8483 | 評價 540 | 評價/貼文 4.62 | 送出評價 5 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 下午 04:29:40
字串長度用 strlen( ) 取得
sizeof(strlen( ) ) 這裡怪怪的

我通常習慣用 sizeof(char) * strlen( ) 來算出 malloc 需要的字串大小
作者 : frank007love(滴可明)
[ 貼文 65 | 人氣 9082 | 評價 20 | 評價/貼文 0.31 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 下午 05:02:52
應該是同樣動作吧
char=1bit
然後我算有幾個字就幾bits
作者 : daniel(冷眼)討論區板主 VC++優秀好手遊戲程式設計優秀好手DirectX優秀好手C++優秀好手貼文超過1000則人氣指數超過70000點
[ 貼文 1564 | 人氣 84169 | 評價 6990 | 評價/貼文 4.47 | 送出評價 15 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 下午 06:21:54
其實只要掌握2個重點..
1.指標要初始代
2.使用前要判斷

//資料檔案
typedef struct File *FileLink;
typedef struct File
{
  File() : FileName(null) ,FileContent(null){};

char *FileName;//檔案名稱
char *FileContent;//檔案內容
FileLink link;//檔案串列
};

//資料閘
typedef struct Folder
{
  Folder() : FolderName(null){};

char *FolderName;//資料閘名稱
FileLink Files;//資料檔案
}Folder;

使用時
if( ptr )
{
....
}

刪除時
SAFE_DELETE(PTR)
作者 : frank007love(滴可明)
[ 貼文 65 | 人氣 9082 | 評價 20 | 評價/貼文 0.31 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 下午 06:38:01
typedef struct File *FileLink;
typedef struct File
{
  File() : FileName(null) ,FileContent(null){}; <----

char *FileName;//檔案名稱
char *FileContent;//檔案內容
FileLink link;//檔案串列
};

//資料閘
typedef struct Folder
{
  Folder() : FolderName(null){}; <----

char *FolderName;//資料閘名稱
FileLink Files;//資料檔案
}Folder;

請問一下這兩個是類似Class的初始化串列嗎?
因為我沒看過把這個放在struct內的寫法= =
我是.c檔案用ANSI C 的語法來檢查程式
好像不能這樣做 要另外初始化

另外我的錯誤如果把結構
typedef struct File
{

char *FileName;//檔案名稱 ->> char FileName[20];
char *FileContent;//檔案內容 ->> char FileContent[256];
FileLink link;//檔案串列
};

改變成字元陣列在free的時候就不會有問題了,
是因為c沒有string嗎?
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人frank007love註記此篇回應為最佳解答 2006/6/28 下午 10:14:54
[刪...]

>//建立一個新的資料閘
>void CreateFolder(Folder *folder,char *foldername)
>{
> folder->FolderName=(char*)malloc(sizeof(strlen(foldername))+1);//給資料閘名稱記憶體

sizeof(strlen()) 得到的是 strlen() 回傳類型的大小.

strlen() 的回傳類型是 size_t, 所以上面的等於 sizeof(size_t). 不會是你想要的結果.

同時, 在 C 語言, malloc() 不需要 typecast.

  folder->FolderName = malloc(strlen(foldername)+1);


> strcpy(folder->FolderName,foldername);//把檔案名稱複製給資料閘
> folder->Files=0;
>}
>
>//增加一個資料閘檔案
>void AddFile(Folder *folder)
>{
> //檔案名稱和檔案內容
> char filename[20],filecontent[256];
> //新增的檔案節點
> FileLink new_ptr;
>
> //輸入檔案名稱和內容
> printf("請輸入檔案名稱: ");
> scanf("\n%s",filename);
> printf("請輸入檔案內容: ");
> scanf("\n%s",filecontent);

這樣寫有兩個問題:

1. 無法防止使用者輸入超出陣列大小的字串, 也就是無法防止 array overflow.
2. 如果你輸入含有空格的字串, filecontent 它只會讀入第一個 word, 其他的都會留在 input buffer .

第一個問題比較嚴重, 會造成安全性的問題.

第二個問題會造成不是你預期的結果, 但留在 input buffer 堛漕銗L字元有可能會在程式的其他地方造成其他的問題.

第一個問題可以用 scanf() 的 width specification 來解決:
  scanf(" %19s", filename);

第二個問題用 scan-set:
  scanf(" %255[^\n]s", filecontent);

註: 長度應該要比陣列的大小少一.

但如果第一個 scanf() 的輸入超出 19 個字元, 或第二個 scanf() 超出 255 個字元, 多餘的字元還是會留在 input buffer , 必須把這些多餘的字元在下一個 scanf() 前刪除掉. 這個下回有機會再討論.


> //給檔案記憶體並且把名稱和內容存入
> new_ptr=(FileLink)malloc(sizeof(FileLink));

'FileLink' 是個指標類型, sizeof(FileLink) 得到的是指標的大小. 你要的應該是 new_ptr 所指向類型的大小.

不需要 typecast.

  new_ptr = malloc(sizeof *new_ptr);


> new_ptr->FileName=(char*)malloc(sizeof(filename)+1);

不需要 malloc() 整個 filename 的長度, malloc() filename 內容的大小就足夠了:

  new_ptr->FileName = malloc(strlen(filename) + 1);


> strcpy(new_ptr->FileName,filename);
> new_ptr->FileContent=(char*)malloc(sizeof(filecontent)+1);

跟上面同理:
  new_ptr->FileContent = malloc(strlen(filecontent)+1);


> strcpy(new_ptr->FileContent,filecontent);
>
> //把檔案放入檔案閘串列
> if(folder->Files==0)//檔案閘無資料-直接放
> {
> new_ptr->link=0;
> folder->Files=new_ptr;
> }
> else//檔案閘有資料-放在頭
> {
> new_ptr->link=folder->Files;
> folder->Files=new_ptr;
> }
>}

[續...]
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 下午 10:15:14
[...續]

>//印出輸入檔案名稱的內容
>void DisplayFileContent(const Folder *folder)
>{
> //檔案名稱
> char filename[20];
> //所要的檔案
> FileLink temp_ptr;
>
> //輸入檔案名稱
> printf("請輸入檔案名稱: ");
> scanf("\n%s",filename);

這裡 scanf() 有同樣的問題:
  scanf("\n%19s",filename);


> //從頭開始找尋所要的檔案名稱

[刪...]

>}
>
>//印出檔案閘所有檔案名稱
>void DisplayAllFiles(const Folder *folder)
>{

[刪...]

>}
>
>//釋放所有用到的記憶體
>void FreeAll(Folder *folder)
>{

[刪...]

>}
>
>void main()

main() 唯一標準的回傳類型是 int:
  int main()

>{

[刪...]

>}

除了上面 scanf() 還沒討論到的東西外, 看來沒有其他問題了.
作者 : frank007love(滴可明)
[ 貼文 65 | 人氣 9082 | 評價 20 | 評價/貼文 0.31 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 下午 10:26:17

原來c不需要typecast,
現在才知道 QQ

我的主要問題是
typedef struct File
{

char *FileName;//檔案名稱
char *FileContent;//檔案內容
FileLink link;//檔案串列
};

這樣的結構去free會有問題
但是
char *FileName;//檔案名稱
char *FileContent;//檔案內容
的部份,變成字元陣列卻不會,
這是我不解的地方

謝謝指教~~
還有sizeof(filename)我不小心打錯= =
作者 : frank007love(滴可明)
[ 貼文 65 | 人氣 9082 | 評價 20 | 評價/貼文 0.31 | 送出評價 7 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2006/6/28 下午 10:27:57
>FileLink' 是個指標類型, sizeof(FileLink) 得到的是指標的大小. 你要的應該是 new_ptr 所>指向類型的大小.

>不需要 typecast.

>new_ptr = malloc(sizeof *new_ptr);

我看到了,
原來是這個問題
作者 : bjk(Up2u) 貼文超過1000則人氣指數超過50000點
[ 貼文 1047 | 人氣 64249 | 評價 730 | 評價/貼文 0.7 | 送出評價 196 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/10/15 下午 04:06:27
能否幫我看看void freeArray(int n)
有的時候可以正常執行,有時候不行
我用dev4.9
另外我如果用VC2008(VC++9.x)
在initial到一半的時候input_array[0]的值會變成-1 ,17 我預期是-1 ,0

struct Node{
    int n;
    struct Node *next;
};

struct Node **input_array;

struct Node *createNode(int n){
    struct Node *temp =malloc(sizeof(struct Node));
    temp->n=n;
    temp->next=NULL;
    return temp;
}
/*
0: -1 , 0
1: -1 , 1
.
.
n: -1, n
*/
void initial(int n){
    int i;
    for(i=0;i<n;i++){
     input_array[i] = createNode(-1);
     input_array[i]->next = createNode(i);
    }
}

void freeArray(int n){
   
    int i=0;
    for(i=0;i<n;i++){
    
     struct Node *temp,*tempFree;
     temp = input_array[i]->next;
    
     //free(input_array[i]);/*這行會死*/
    
     while(temp!=NULL){
    
     tempFree = temp;
    
     temp = temp->next;
    
     free(tempFree);/*這行有時候會死*/
    
     };
    }
    free(input_array);
   
}


int main(int argc, char *argv[])
{
    int input_n;
    scanf("%d",&input_n);
    input_array = malloc(sizeof(struct Node*));
    initial(input_n);
}
作者 : bjk(Up2u) 貼文超過1000則人氣指數超過50000點
[ 貼文 1047 | 人氣 64249 | 評價 730 | 評價/貼文 0.7 | 送出評價 196 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/10/15 下午 04:57:35
完整的程式碼如下

http://codepad.org/gbBIJnSd
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/10/15 下午 09:14:26
你應該另行發文, 不要劫持別人的貼文.

>int main(int argc, char *argv[])
>{
> int input_n;
> scanf('%d',&input_n);
> input_array = malloc(sizeof(struct Node*));

你配置了多少個的 Node*?

> initial(input_n);
>}

>完整的程式碼如下
>
>http://codepad.org/gbBIJnSd

你用 C99 語言? 會這樣問的原因是完整程式裡的語法不是 C90 的語法.

GCC 編譯器的預設是使用 GNU 自己的語言延伸. 在你的 command line option 裡, 加入以下的 options:
-ansi -pedantic -Wall

作者 : bjk(Up2u) 貼文超過1000則人氣指數超過50000點
[ 貼文 1047 | 人氣 64249 | 評價 730 | 評價/貼文 0.7 | 送出評價 196 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2010/10/16 上午 07:23:07
>你應該另行發文, 不要劫持別人的貼文.
好的

>你配置了多少個的 Node*?
改過後用DEV就可以了謝謝
但是我用VC跑還是不行,
scanf("%d",&input_n);
input_array = (struct Node**)malloc(sizeof(struct Node*)*input_n);

>你用 C99 語言? 會這樣問的原因是完整程式裡的語法不是 C90 的語法.
>
爬了一下文,C99比較少編譯器支援,所以我的目標是熟練C90
請問業界比較常用的是哪一種呢?

>GCC 編譯器的預設是使用 GNU 自己的語言延伸. 在你的 command line option 裡, 加入以下的 options:
>-ansi -pedantic -Wall

dev好像是按alt+p專案設定
http://yfrog.com/n1001lcp

我練習題目是要丟給ACM的編譯器
他的版本是
ANSI C 4.1.2 - GNU C Compiler with options: -lm -lcrypt -O2 -pipe -ansi -DONLINE_JUDGE
網址
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=25&page=submit_problem&category=&mosmsg=Submission+received+with+ID+8322401
 板主 : simula
 > C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C++
1 Raymond 13050 
2 青衫 4760 
3 simula 4690 
4 coco 4030 
5 白老鼠(Gary) 3670 
6 ozzy 2540 
7 Ben 2250 
8 Anderson 1960 
9 windblown 1650 
10 Kenny 1560 
C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.203125