[英]c programming malloc question
剛剛得到有關c malloc()函數的查詢。 我正在從文件中讀取()x個字節以獲取文件名的長度,例如'read(file,&namelen,sizeof(unsigned char)); '。
變量namelen是一個無符號字符類型,並以該類型(1字節)寫入文件。 現在namelen具有文件名的長度,即namelen = 8(如果文件名是'data.txt'),加上末尾的/ 0,則可以正常工作。
現在,我有一個結構來記錄文件信息,即文件名,文件長度,內容大小等。
struct fileinfo
{
char *name;
...... other variable like size etc
};
struct fileinfo *files;
問題:我想使files.name變量的大小為namelen的大小,即8,這樣我就可以成功地將文件名寫入其中,例如'files [i] .name = malloc(namelen)'
但是,我不希望它是malloc(sizeof(namelen)),因為那樣會使它成為file.name [1],因為它的類型為unsigned char。 我希望它是存儲在變量&namelen中的值,即8,所以file.name [8]以便data.txt可以從文件中作為8個字節讀取()並直接寫入file.name [8?
有沒有辦法做到這一點,我目前的代碼是這樣,並返回4而不是8
files[i].name = malloc(namelen);
//strlen(files[i].name) - returns 4
//perhaps something like
malloc(sizeof(&namelen)) but does not work
感謝您的任何建議
曾經嘗試過建議的建議,但是我現在使用以下方法得到了分段錯誤錯誤:
printf("\nsizeofnamelen=%x\n",namelen); //gives 8 for data.txt
files[i].name = malloc(namelen + 1);
read(file, &files[i].name, namelen);
int len=strlen(files[i].name); printf("\nnamelen=%d",len);
printf("\nname=%s\n",files[i].name);
當我嘗試使用該files [i] .name變量打開()文件時,它不會打開,因此似乎不會在read()&files [i] .name和strlen()內部寫入數據,這也會導致隔離錯誤嘗試打印文件名
strlen(name) + 1
個字節長(由於終止\\0
)。 namelen = strlen("data.txt")
(即8),則必須分配files[i].name = malloc(namelen + 1)
malloc()
分配的任何內存都是undefined 。 您不能在剛剛分配的內存上執行strlen()
-您必須先設置已分配的內存 strncpy( files[i].name, "data.txt", namelen + 1 )
, 然后才可以strlen( files[i].name )
您擁有的代碼(幾乎)是分配內存的正確方法,您需要為尾隨的NULL字節包括空間:
files[i].name = malloc(namelen + 1);
請注意,此時字符串尚未初始化,因此strlen(files[i].name)
將返回隨機的崩潰次數。 您可以使用memset()
將內存清零,然后strlen(files[i].name)
將返回0。如果從文件中讀取數據, strlen(files[i].name)
將返回8。
malloc返回未初始化的內存,因此結果為
strlen(files[i].name)
之后
files[i].name = malloc(namelen);
未定義。
並且strlen
對字符進行計數,直到內存塊中的第一個'\\ 0'字符為止-它不返回由以前的malloc
調用分配的內存塊大小。
關於問題更新:
read
不會以'\\ 0'字符終止目標,這就是為什么會出現分段錯誤的原因。
插入一個
files[i].name[namelen] = '\0';
正確終止C字符串,應解決此問題。
另外,您可以使用calloc
代替malloc。
如果文件名不變,您可以提高效率,並在同一malloc()
分配文件名的結構和空間:
struct fileinfo *files = malloc(sizeof *files + namelen + 1);
files->name = (char *) (files + 1);
這將分配一個單獨的內存塊,該內存塊足以容納struct fileinfo
(即sizeof *files
字節)和以'\\ 0'結尾的文件名( namelen + 1
)。 第二行在結構本身之后的第一個字節處使結構點的name
成員。
然后,您可以繼續進行操作,例如通過將另一個調用read()
加載來將文件名寫入files->name
。
完成后,您可以通過一次調用free(files)
釋放整個結構,包括文件名。
read(file, &files[i].name, namelen);
應該
read(file, files[i].name, namelen);
因為files [i] .name存儲分配的緩沖區的地址。 由於讀取的原型是無效的*,因此您的編譯器可能會讓您不通過傳遞char **而不是報告錯誤。
同樣如maxschlepzig所說,不要忘記在緩沖區的末尾添加\\ 0。
您是否為文件分配了空間? 當前,它是struct fileinfo *文件;
假設您執行了以下操作:files = malloc(sizeof(struct fileinfo)* num_files);
printf("\nsizeofnamelen=%x\n",namelen); //gives 8 for data.txt
files[i].name = malloc(namelen + 1);
read(file, &files[i].name, namelen);
files[i].name[namelen] = '\0'; // NUL-terminate the string.
int len=strlen(files[i].name); printf("\nnamelen=%d",len);
printf("\nname=%s\n",files[i].name);
如果您不對字符串(file [i] .name)進行NUL終止,那么您將繼續讀取隨機內容,並可能讀取段錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.