动态数组和功能化 malloc [重复]

Posted

技术标签:

【中文标题】动态数组和功能化 malloc [重复]【英文标题】:Dynamic array and functionalize malloc [duplicate] 【发布时间】:2017-03-08 07:46:10 【问题描述】:

我尝试在函数上malloc一个数组,这个函数也可以检查内存是否足够。

第一个代码块无法工作。 当它执行“*pi = 5”时,编译器会显示这个错误信息“Thread 1: EXC_BAD_ACCESS(code=1, address=0x0) "”。

 #include <stdio.h>
 #include <stdlib.h>

 void malloc_and_check(int *var)
 
     if(!(var = (int*)malloc(sizeof(int))))
     
        fprintf(stderr, "Insufficient Memory\n");
        exit(EXIT_FAILURE);
      
 

 int main(int argc, const char * argv[]) 
 
    int *pi;
    malloc_and_check(pi);
    *pi = 5;
    printf("%d", *pi);
    free(pi);
 

但是,下面的代码可以正常工作。

    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, const char * argv[])
    
        int *pi;

        if(!(pi = (int*)malloc(sizeof(int))))
        
            fprintf(stderr, "Insufficient Memory\n");
            exit(EXIT_FAILURE);
        

        *pi = 5;
        printf("%d", *pi);
        free(pi);
    

它们之间有什么区别?谢谢!

【问题讨论】:

你必须通过void malloc_and_check(int **var)并用malloc_and_check(&amp;pi);调用它另外不要强制malloc的返回 malloc失败时使用perror("malloc"); exit(EXIT_FAILURE); 【参考方案1】:

您正在尝试按值传递指针(按值传递)。您需要将双指针传递给函数malloc_and_check。因此,分配给指针的值不会反映在调用者中。

请修改您的代码如下:

 #include <stdio.h>
 #include <stdlib.h>

 void malloc_and_check(int **var)
 
     if(!(*var = malloc(sizeof(int))))
     
        fprintf(stderr, "Insufficient Memory\n");
        exit(EXIT_FAILURE);
      
 

 int main(int argc, const char * argv[]) 
 
    int *pi;
    malloc_and_check(&pi);
    *pi = 5;
    printf("%d", *pi);
    free(pi);
 

【讨论】:

我在 3 秒前抓住了你 :) 摆脱 malloc 的演员阵容 @David, : ))。完成! 完美。我会给你这样的景象,但我正在更换笔记本电脑并且失去了我的第二个快速参考大脑(篮子记事本 - kde3)【参考方案2】:

您在函数中对var 所做的更改会在函数返回时丢失。要么您需要将var 作为双指针传递,要么您需要从函数返回一个指针。

函数返回指针的示例:

 #include <stdio.h>
 #include <stdlib.h>

 int* malloc_and_check()
 
     int *var;
     if(!(var = malloc(sizeof(int))))
     
        fprintf(stderr, "Insufficient Memory\n");
        exit(EXIT_FAILURE);
      
     return var;
 

 int main(int argc, const char * argv[]) 
 
    int *pi;
    pi = malloc_and_check();
    *pi = 5;
    printf("%d", *pi);
    free(pi);
 

【讨论】:

分配退货是另一种选择,但从技术上讲,这是对一个稍微不同的问题的答案。 (但我不会分头发)【参考方案3】:

当您将int * var 传递给malloc_and_check 时,您正在更新指针的本地副本,因此原始副本保持不变。您可以通过两种方式解决此问题: (a) 从malloc_and_check返回指针

int * malloc_and_check()

    int * var = 0;
    if(!(var = (int*)malloc(sizeof(int))))
    
        fprintf(stderr, "Insufficient Memory\n");
        return 0;
     
    return var;
  

那你就叫它

pi = malloc_and_check();

(b) 传入一个指向指针的指针

void malloc_and_check(int ** var)

    if(!( *var = (int*)malloc(sizeof(int))))
    
        fprintf(stderr, "Insufficient Memory\n");
        exit(EXIT_FAILURE);
     
  

然后你会把它作为

 malloc_and_check(&pi);

【讨论】:

是的,另一种解释方式是,当任何东西作为函数参数传递时,函数会收到一个 copy(带有自己的,和非常不同的地址)。在分配指针的情况下,没有区别,因为指针的value仍然指向原始内存块。但是,对于未分配的指针,malloc 返回的地址被分配给指针的副本,并且与main 中的原始指针地址没有关联。 (这也会导致内存泄漏)【参考方案4】:

指针 var 是动态分配的内存,但它是函数 malloc_and_check 的本地。函数 main 中的指针 pi 不会知道分配给 var 的内存地址。这是一个错误的访问,有时也可能导致崩溃。

尝试下面的代码以获得预期的结果:

#include <stdio.h>
 #include <stdlib.h>

 void malloc_and_check(int **var)
 
     int *var1;
     if(!(var1 = (int*)malloc(sizeof(int))))
     
        fprintf(stderr, "Insufficient Memory\n");
        exit(EXIT_FAILURE);
      
     else 
        *var = var1;
 

 int main(int argc, const char * argv[]) 
 
    int *pi;
    malloc_and_check(&pi);
    *pi = 5;
    printf("%d", *pi);
    free(pi);
 

【讨论】:

以上是关于动态数组和功能化 malloc [重复]的主要内容,如果未能解决你的问题,请参考以下文章

“字符串”数组的动态分配[重复]

C语言中malloc和静态数组最多能开到多大呢

使用 malloc 的 MPI 动态数组

C分配双精度的动态数组并用memset初始化它[重复]

C语言 如何给指针数组划分动态存储空间

c语言动态数组如何扩充空间