简体   繁体   中英

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:

#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

It seems you are trying to malloc something that looks like a 2D array (or rather an array of strings).

However,

def(B);

is a call by value so B doesn't change when the function returns.

If you want to change B you need

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

and read the answer given by @Lundin - that's the way to do it

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. Part 1 of your problem is that you need to be providing a pointer to your list:

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. 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.

#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(&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. 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. So in this case the statement

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

does NOT alter the pointer B declared in main() ; it just leaks memory. Assuming you really need to return an int for this function, you need to add a level of indirection:

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

You problem is that when you call def(B) , you are creating a char ** that is a copy of 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 .

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 .

Also, check the problems pointed in other answers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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