簡體   English   中英

時間:2019-04-01標簽:callocm編程

[英]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()內部寫入數據,這也會導致隔離錯誤嘗試打印文件名

  1. 字符串為strlen(name) + 1個字節長(由於終止\\0 )。
  2. 如果namelen = strlen("data.txt") (即8),則必須分配files[i].name = malloc(namelen + 1)
  3. 您使用malloc()分配的任何內存都是undefined 不能在剛剛分配的內存上執行strlen() -您必須先設置已分配的內存
  4. 只有分配了內存后,才能使用內存,即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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM