[英]pointer without a malloc
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(){
struct stat *something;
stat("/etc/profile", something);
printf("%d\n", something->st_gid);
free(something);
return 0;
}
$ ./a.out
Segmentation fault
我從這篇文章中學到 ,我需要使用malloc分配內存,因此我將其更改為如下所示,並且可以正常工作:
- struct stat *something;
+ struct stat *something = malloc(sizeof(struct stat));
在先前但相關的練習中,我沒有使用malloc,並且它起作用了。 我搞不清楚了! 為什么在下面的行“ * struct dirent b; ”中不需要malloc?
或者,換句話說,我們如何才能知道有效負載太多並使用malloc?
#include <stdio.h>
#include <dirent.h>
int main(int argc, char *argv[]){
if (argc != 2){
printf("Error. Syntax: ls <somefolder> \n");
return 1;
}
DIR *a = opendir(argv[1]) ;
if (a == NULL){
printf("error. cannot open %s\n", argv[1]);
return 1;
}
// - malloc question about this very next line
struct dirent *b;
while (( b = readdir(a)) != NULL){
printf("%s %lu\n", b->d_name, b->d_ino);
}
int closing = closedir(a);
printf("in closing, status is %d\n", closing);
return 0;
}
C的新手,也很無知-請保持溫柔! :)
問題所在
struct stat *something;
stat("/etc/profile", something);
是something
是指向無處的未初始化指針,這會產生未定義的行為,因為stat
會在無效地址上寫入某物。 使用malloc
您可以為其分配內存,並將指向該已分配內存位置的指針傳遞給stat
,這就是它起作用的原因。
但你並不需要使用malloc
為,只是不申報something
作為指針:
struct stat something;
stat("/etc/profile", &something); // <-- look at the usage of &
在stat
您應使用&
運算符,它返回指向something
的指針。
在您的其他程序中
struct dirent *b;
while (( b = readdir(a)) != NULL)
readdir
返回指向有效位置的指針,該函數本身負責使用有效對象並返回指向該對象的指針。 但是,您不能執行free(b)
:
返回值
成功后,
readdir()
返回一個指向dirent結構的指針。 (此結構可能是靜態分配的;請勿嘗試將其free(3)
。)
readdir
返回一個指向struct dirent
的指針。 這樣做: b = readdir(a)
用readdir
返回的新值覆蓋值b
。
所以b
先前已使用malloc
調用中分配的內存進行了初始化,該值已被覆蓋,您現在可能會發生內存泄漏。
您可能想知道然后是否需要在readdir
調用之后在b
free
調用。 要回答這個問題,您必須查閱文檔。 在這種情況下,答案是否定的 。
從readdir
的文檔中:
成功后,readdir()返回一個指向dirent結構的指針。 (此結構可能是靜態分配的;請勿嘗試將其釋放(3)。)
int main(){
struct stat *something;
stat("/etc/profile", something);
printf("%d\n", something->st_gid);
free(something);
return 0;
}
上面的代碼有多個問題,
something
未指向有效的位置,並再次使用它作為一個緩沖區來存儲信息返回stat()
int stat(const char *路徑名,struct stat * statbuf);
stat()
在statbuf
指向的緩沖區中返回有關文件的信息,因此您的statbuf
(某物)應該是有效的緩沖區,其大小足以存儲文件信息,即struct stat
大小。
free(something);
來自free()手冊頁
如果傳遞給free()的參數與POSIX.1-2008中的函數返回的指針較早的指針不匹配,該函數像malloc()那樣分配內存,或者如果通過調用free()或realloc釋放了空間(),行為未定義。
現在來看其他代碼:
// - malloc question about this very next line
struct dirent *b;
while (( b = readdir(a)) != NULL){
printf("%s %lu\n", b->d_name, b->d_ino);
}
讓我們來探討一下readdir()
,
struct dirent * readdir(DIR * dirp); readdir()函數返回一個指向dirent結構的指針,該結構表示dirp指向的目錄流中的下一個目錄條目。 在到達目錄流的末尾或發生錯誤時,它返回NULL。
你看readdir()
返回一個指針struct dirent
類型,這使得b
在struct dirent *b
的有效指針。 這就是為什么它起作用。
通常,任何指針,無論是int *ptr
還是char *ptr
還是struct student *ptr
,它都應具有valid address
並且有效地址可以是動態分配的地址或某些變量的地址 。
案例1 : struct stat *something;
這里有something
是struct stat
類型的指針,它是未初始化的。
當你做stat("/etc/profile", something);
您要存儲/etc/profile
信息到something
是未初始化。 代替此,您應該將/etc/profile
的信息存儲到something
地址或
struct stat info;
struct stat *something = &info;
stat("/etc/profile",something );
情況2 : struct dirent *b;
b
是struct dirent
類型的指針,它也應具有有效地址。 b = readdir(a);
readdir
返回值已分配給b
,因此現在您可以執行b->d_name
等。
從readdir()
的手冊頁
成功后,readdir()返回一個指向dirent結構的指針。 (此結構可能是靜態分配的;請勿嘗試將其釋放(3)。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.