c - 动态数组分配,按值传递,超出范围

标签 c arrays pointers dynamic-memory-allocation

我有两个关于动态分配数组的问题。我查了一些类似的问题,但仍然没有找到答案。

  1. 按值传递

    基本上,我编写了两个函数,一个用于分配,另一个用于释放内存。当我按值传递数组指针时,分配函数不起作用(如预期),但自由函数起作用。在我天真的理解中,即使我们按值传递数组指针,分配仍然应该有效,因为它在与所表示的值相同的内存地址处分配内存。如果我们稍后引用该地址,无论变量名称如何,我们都应该能够找到该空间。这是代码:

    void main()
    {
       int * array;
       allocation(array);
       deallocation(array);
    }
    
    void allocation(int * result)
    {
       result = malloc(8293 * sizeof(result));
    }
    
    void deallocation(int * result)
    {
       free(result);
    }
    

    对于释放测试,我在主函数中声明了 int * array = malloc(23123* sizeof(int)) 而不是使用分配函数。再次,释放有效。

  2. 超出范围访问。

    void main()
    {
        FILE * fp = fopen("sometext.txt");
    
        int * A = malloc(100 * sizeof(int));
        int * B = malloc(200 * sizeof(int));
    
     /* Now I accidentally access A from 0-199 and B from 0-999 using a for loop*/
        char buffer[500];
        int i,x;
    
         for (i=0; i<200; i++)
         {  
              fgets(fp,buffer);
              sccanf(buffer, "%d", x);
              A[i]=x;
         }
    
         for (i=0; i<1000; i++)
         {  
              fgets(fp,buffer);
              sccanf(buffer, "%d", x);
              B[i]=x;
         }
    }
    

    两个 for 循环都不应该工作。然而,我以某种方式通过了第一个循环,并且只在第二个循环中出现了段错误。我得到的错误可以追溯到 sccanf (我测试了代码,没有为 A 或 B 分配任何值,并且它有效。所以 sccanf 语句应该没问题。) gdb 错误消息是: isoc99_sscanf (s=, format= )。

完整的 bt 消息如下,SOL[] 是我的 B[],实际的 sscanf 读取更多变量。如果您有兴趣,我可以发布完整的代码。

  #0  0x00007ffff7a6869b in _IO_vfscanf_internal (s=s@entry=0x7fffffffd3b0, 
    format=format@entry=0x4010f8 "%*d%5c%5c%5d %lf %lf %lf %*f %*f %*f\n", 
  argptr=argptr@entry=0x7fffffffd4d8, errp=errp@entry=0x0) at vfscanf.c:343
 #1  0x00007ffff7a72a0c in __GI___isoc99_vsscanf (
     string=0x7fffffffd650 " 4545SOL    HW123234   2.687   0.089   7.120 -1.1448  0.0920  0.6016\n", format=0x4010f8 "%*d%5c%5c%5d %lf %lf %lf %*f %*f %*f\n", 
   args=args@entry=0x7fffffffd4d8) at isoc99_vsscanf.c:43
 #2  0x00007ffff7a72997 in __isoc99_sscanf (s=<optimized out>, 
  format=<optimized out>) at isoc99_sscanf.c:31
 #3  0x0000000000400a9c in read (PMI=0x603490, COION=0x606ce0, 
     COUNTERION=0x60dd70, SOL=0x7ffff7f58010, in=0x603010, out=0x603250)
   at thick_calc.c:97
 #4  0x0000000000400915 in main () at thick_calc.c:52

谢谢!

最佳答案

  1. 您没有重新分配指针,它应该是

    void main()
    {
       int * array;
       allocation(&array);
       if (array != NULL)
           deallocation(array);
    }
    
    void allocation(int **result)
    {
       if (result == NULL)
           return;
       *result = malloc(8293 * sizeof(int));
    }
    
    void deallocation(int * result)
    {
       free(result);
    }
    

    通过传递指针,你可以修改它的内容,但你不能改变它指向的位置,所以你必须传递一个指针到指针,即指针的地址,这样你才能修改它指向的位置。

    代码中的问题是您的指针在 main 范围内仍然无效,因此当您将其传递给 free 时,它实际上并不指向 malloced 内存阻止。

  2. 这样做会导致未定义的行为。读取或写入超过 malloced block 会导致未定义的行为,因此您不能期望给定的行为,因为它是未定义的。

    这意味着,它可能会导致段错误,或者它可以工作,或者因为未定义而可能发生任何事情。

    最终你会写入内存中的一个特殊位置,并且会发生一些事情,你无法确定同时发生了什么,因为这又是未定义的行为。

关于c - 动态数组分配,按值传递,超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28199575/

相关文章:

c - C 计算字符串中字符数的函数

c - C-此指针为空吗?

c++ - 为什么我不能像这样: int *p = 6;?直接给int指针赋值

c - 将 A71CH 与 I2C 连接

c - 汇编语言是如何生成机器码的?

arrays - 在 Collection View 中使用来自转义闭包的数组

javascript - 从列表中查找对象数组中的值

java - 如何使用 ssjs 数组变量设置组合框的值?

c++ - 如何理解复杂的数组声明指针,以及 &

嵌套列表的 C 等价物 (Python)