簡體   English   中英

函數內部c中的Malloc使用

[英]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);

然后您需要相應地更改函數簽名-然后您將成為三星級程序員。

如果要正確執行此操作,請閱讀:

通過將指針傳遞給c中的函數來創建2D數組

並閱讀@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.

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