繁体   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