[英]Malloc usage in c inside a function
我試圖傳遞一個指向函數的指針。在這個函數中,我使用malloc來保留空間。問題是當我返回main時程序沒有響應,這是我的簡化代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int def(char **B){
int i;
B = malloc(3 * sizeof( char ));
for(i = 0; i < 2 ; i++){
B[i] = malloc(5 * sizeof(char));
}
for(i = 0; i < 2 ; i++){
scanf("%s" , B[i]);
}
for(i = 0; i < 2 ; i++){
printf("%s\n" , B[i]);
}
return 0;
}
int main(int argc, char *argv[]) {
char **B;
int i;
def(B);
for(i = 0; i < 2 ; i++){
printf("%s\n" , B[i]);
}
return 0;
}
int def(char **B)
本來應該
char** def(char **B)
它的返回值應該是
return B;
/* else the memory allocated inside the function will be freed at
* the end and by accessing it later you have undefined behavior for the
* rest of the program
*/
B = malloc(3 * sizeof( char ));
本來應該
B = malloc(3 * sizeof( char*)); // you have two levels of indirection. so char* first
for(i = 0; i < 2 ; i++) // similary with the other for loops
本來應該
for(i = 0; i < 3 ; i++) // you used 3 in the above step
def(B);
本來應該
B=def(B);
最好使用free()
釋放分配的內存,盡管它將在程序結束時自動釋放
看來您正在嘗試分配看起來像2D數組(或字符串數組)的東西。
然而,
def(B);
是按值調用,因此函數返回時B
不會改變。
如果要換B
def(&B);
然后您需要相應地更改函數簽名-然后您將成為三星級程序員。
如果要正確執行此操作,請閱讀:
並閱讀@Lundin給出的答案-這就是這樣做的方法
您似乎正在嘗試分配一個字符串列表,但是您無法在def
函數之外提供引用此字符串的功能。 問題的第1部分是您需要提供指向列表的指針:
int def(char ***B) {
另一個選擇是返回您創建的指針:
char** def() {
其次,在您的第一個malloc中,您為3個chars
分配空間,但是您需要char
指針。 sizeof char != sizeof char*
。
B = malloc(3 * sizeof( char ));
應該:
*B = malloc(3 * sizeof char*);
另外,您應該使用const int
或#define
定義尺寸常數,這樣就不會在不同的地方意外地得到錯誤的尺寸,例如。
#define SIZE_OF_LIST 3
int def(char ***B){
int i;
B = malloc(SIZE_OF_LIST * sizeof( char ));
for(i = 0; i < SIZE_OF_LIST ; i++){
最后,當您將指針傳遞給函數def
您需要這樣做(頂部容納第一個更改):
def(&B);
要么
B = def();
實際上,這比那更糟。 所有C函數參數都是“按值”,這意味着函數內部的變量是在調用中傳遞的變量的本地副本。 因此,當您為參數分配一個值時(除非聲明為'const',否則您可以這樣做[我假設現在C中已經采用C ++'const'] ),您不會分配給傳入的變量在電話。 所以在這種情況下
B = malloc(3 * sizeof(char *));
不會更改main()中聲明的指針B ; 它只會泄漏內存。 假設您確實需要為此函數返回一個int ,則需要添加一個間接級別:
int def(char ***B){
*B = malloc(3 * sizeof(char *));
for(i=0; i<2; i++){
(*B)[i] = malloc(5 * sizeof(char));
}
...
}
...
char **B;
...
def( &B ); /* Note the 'address-of' operator! */
如果返回不必是int :消除def()的參數,將其更改為返回**** char **,直接返回第一個malloc()的結果,並將調用更改為B = def ();
您的問題是,當您調用def(B)
,您正在創建一個char **
,它是B
的副本 。 如果更改此新B
,則更改不會反映在main函數上,因為這些更改是對B
的副本進行的。
您應該使用char ***
並調用def(&B)
(我不認為這是一個好方法,但是)或者您可以在主程序中初始化B
並調用def(B)
來分配和讀取其char *
或者可以返回新的B
另外,檢查其他答案中指出的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.