简体   繁体   English

函数内部c中的Malloc使用

[英]Malloc usage in c inside a function

I am trying to pass a pointer to a function.In this function i use malloc to reserve space.The problem is that when i return in main the program doesn't respond.Here is my symplified code: 我试图传递一个指向函数的指针。在这个函数中,我使用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)

should have been 本来应该

char** def(char **B) 

and its return value should have been 它的返回值应该是

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 ));

should have been 本来应该

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

should have been 本来应该

 for(i = 0; i < 3 ; i++) // you used 3 in the above step


def(B);

should have been 本来应该

B=def(B);

It is a good practice to use free() to free the allocated memory though it will be automatically freed at the end of the program 最好使用free()释放分配的内存,尽管它将在程序结束时自动释放

It seems you are trying to malloc something that looks like a 2D array (or rather an array of strings). 看来您正在尝试分配看起来像2D数组(或字符串数​​组)的东西。

However, 然而,

def(B);

is a call by value so B doesn't change when the function returns. 是按值调用,因此函数返回时B不会改变。

If you want to change B you need 如果要换B

def(&B);

and then you need to change the function signature accordingly - then you'll be a three star programmer. 然后您需要相应地更改函数签名-然后您将成为三星级程序员。

If you want to do this correct then read: 如果要正确执行此操作,请阅读:

Create 2D array by passing pointer to function in c 通过将指针传递给c中的函数来创建2D数组

and read the answer given by @Lundin - that's the way to do it 并阅读@Lundin给出的答案-这就是这样做的方法

You seem to be trying to allocate a list of strings, but you do not provide the ability to reference this outside the def function. 您似乎正在尝试分配一个字符串列表,但是您无法在def函数之外提供引用此字符串的功能。 Part 1 of your problem is that you need to be providing a pointer to your list: 问题的第1部分是您需要提供指向列表的指针:

int def(char ***B) {

Another option is to return the pointer you have created: 另一个选择是返回您创建的指针:

char** def() {

Secondly in your first malloc you allocate space for 3 chars but you need char pointers. 其次,在您的第一个malloc中,您为3个chars分配空间,但是您需要char指针。 sizeof char != sizeof char* . sizeof char != sizeof char*

B = malloc(3 * sizeof( char ));

Should be: 应该:

*B = malloc(3 * sizeof char*);

Also you should use const int or #define to define your size constants so you dont accidentally get the wrong size in different places, eg. 另外,您应该使用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++){

Finally when you pass your pointer to the function def you need to do this (top accommodate the first change): 最后,当您将指针传递给函数def您需要这样做(顶部容纳第一个更改):

def(&B);

or 要么

B = def();

Actually, it is worse than that. 实际上,这比那更糟。 All C function arguments are 'by value', meaning that the variables inside the function are local copies of the variables passed in at the call. 所有C函数参数都是“按值”,这意味着函数内部的变量是在调用中传递的变量的本地副本。 So when you assign a value to an argument (which you are allowed to do, unless it is declared 'const' [I assume C++ 'const' has been adopted in C by now] ), you are NOT assigning to the variable passed in at the call. 因此,当您为参数分配一个值时(除非声明为'const',否则您可以这样做[我假设现在C中已经采用C ++'const'] ),您不会分配给传入的变量在电话。 So in this case the statement 所以在这种情况下

B = malloc(3 * sizeof(char *));

does NOT alter the pointer B declared in main() ; 不会更改main()中声明的指针B it just leaks memory. 它只会泄漏内存。 Assuming you really need to return an int for this function, you need to add a level of indirection: 假设您确实需要为此函数返回一个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! */

If the return doesn't have to be int : eliminate the argument to def() , change it to return ****char**, return the result of the first malloc() directly, and change the call to B = def(); 如果返回不必是int :消除def()的参数,将其更改为返回**** char **,直接返回第一个malloc()的结果,并将调用更改为B = def ();

You problem is that when you call def(B) , you are creating a char ** that is a copy of B . 您的问题是,当您调用def(B) ,您正在创建一个char ** ,它是B副本 If you change this new B , the changes doesn't reflect on the main function, since they were made to the copy of B . 如果更改此新B ,则更改不会反映在main函数上,因为这些更改是对B的副本进行的。

You should use a char *** and call def(&B) (i do not consider this a good approach, tho) or you could have B initialized at the main and call def(B) to alloc and read its char * or you could return the new B . 您应该使用char ***并调用def(&B) (我不认为这是一个好方法,但是)或者您可以在主程序中初始化B并调用def(B)来分配和读取其char *或者可以返回新的B

Also, check the problems pointed in other answers. 另外,检查其他答案中指出的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM