Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 运行时使用free()而不是调试时使用free()时发生访问冲突。。。慢速地_C_Free_Access Violation - Fatal编程技术网

C 运行时使用free()而不是调试时使用free()时发生访问冲突。。。慢速地

C 运行时使用free()而不是调试时使用free()时发生访问冲突。。。慢速地,c,free,access-violation,C,Free,Access Violation,根据我之前对Jonathan Leffler的感谢,我编辑了第二个两段代码,但遇到了一个相当奇怪的问题 下面的一个不可预测地中断 void free_array(array_info *A) { int i; for(i = 0; i < (A->height); ++i) { printf("About to free: %x\n", A->dat_ptr[i]);//for debugging purposes fre

根据我之前对Jonathan Leffler的感谢,我编辑了第二个两段代码,但遇到了一个相当奇怪的问题

下面的一个不可预测地中断

void free_array(array_info *A)
{
    int i;
    for(i = 0; i < (A->height); ++i)
    {
        printf("About to free: %x\n", A->dat_ptr[i]);//for debugging purposes
        free(A->dat_ptr[i]);
        printf("Freed row %i\n", i);//for debugging purposes
    }
    free(A->dat_ptr);
}
其中dat_ptr现在是一个正确的2D指针。创建要放入结构中的数组的create_array函数是我已去除了可读性的空检查:

int create_array(array_info *A)
{
int i;
unsigned int **array = malloc(sizeof(*array) * A->height);

for (i = 0; i < A->height; ++i)
{
    array[i] = malloc(sizeof(**array) * A->width);
}

A->dat_ptr = array;
return 0;
}
此函数完全按照预期工作

更多附加信息 在Jonathan、Chris和Rharrison的回复后添加33 非常感谢你,乔纳森,通过你的每一篇帖子,我发现了很多关于编程的东西:我终于找到了罪魁祸首。导致异常的代码如下所示:

void fill_number(array_info* array,  int value,  int x1,  int y1,  int x2,  int y2)//fills a rectangular part of the array with `value`
    {
    int i, j;
    for(i=y1 ; ((i<=y2)&&(i<array->height)) ; i++)//start seeding the values by row (as in vertically)
    {
        for(j=x1 ; ((i<=x2)&&(i<array->width)) ; j++)//seed the values by columns (as in horizontally)
        {
        array->dat_ptr[i][j]=value;
        }
    }
}

我相信你说得不对。尝试将create_array函数修改为:

int create_array(array_info *A)
{
  int i;
  unsigned int **array = malloc(sizeof(unsigned int*) * A->height);

  for (i = 0; i < A->height; ++i)
  {
    array[i] = malloc(sizeof(unsigned int) * A->width);
  }

  A->dat_ptr = array;
  return 0;
}

我相信你说得不对。尝试将create_array函数修改为:

int create_array(array_info *A)
{
  int i;
  unsigned int **array = malloc(sizeof(unsigned int*) * A->height);

  for (i = 0; i < A->height; ++i)
  {
    array[i] = malloc(sizeof(unsigned int) * A->width);
  }

  A->dat_ptr = array;
  return 0;
}

这段代码紧密地基于您从我这里得到的信息以及您在上面所写的内容,看起来工作正常。请注意和PRIXPTR的使用以及uintptr的转换。它避免了对指针大小的假设,并且在32位和64位系统上同样有效,尽管%.8意味着您在32位编译中可以获得完整的8位十六进制值,在这个特定的64位平台上,最多可以得到16个十六进制值中的12个

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

typedef struct
{
    int    height;
    int    width;
    int    bottom;
    unsigned int **dat_ptr;  // Double pointer, not triple pointer
} array_info;

static void create_array(array_info *A)
{
    unsigned int **array = malloc(sizeof(*array) * A->height);
    printf("array (%zu) = 0x%.8" PRIXPTR "\n",
           sizeof(*array) * A->height, (uintptr_t)array);
    for (int i = 0; i < A->height; ++i)
    {
        array[i] = malloc(sizeof(**array) * A->width);
        printf("array[%d] (%zu) = 0x%.8" PRIXPTR "\n",
               i, sizeof(**array) * A->width, (uintptr_t)array[i]);
    }
    A->dat_ptr = array;
}

static void free_array(array_info *A)
{
    int i;
    for(i = 0; i < (A->height); ++i)
    {
        printf("About to free %d: 0x%.8" PRIXPTR "\n",
               i, (uintptr_t)A->dat_ptr[i]);
        free(A->dat_ptr[i]);
    }
    printf("About to free: 0x%.8" PRIXPTR "\n", (uintptr_t)A->dat_ptr);
    free(A->dat_ptr);
}

int main(void)
{
    array_info array = { .height = 5, .width = 10, .dat_ptr = 0 };
    create_array(&array);
    if (array.dat_ptr == 0)
    {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    free_array(&array);
    puts("OK");
    return(0);
}
我在这台机器上没有valgrind,但是分配和释放的地址可以被肉眼看到,表明没有明显的问题。巧合的是,我调整了数组的大小,使它们在64位机器上都是40字节

后续问题 你还在用你的数据做什么? 您分配的阵列有多大? 你确定没有遇到算术溢出吗? 在Mac OS X 10.8.2和GCC/Clang的XCode版本上进行测试:

i686-apple-darwin11-llvm-gcc-4.2 gcc 4.2.1基于苹果公司构建5658 llvm构建2336.11.00

阵列设置和打印功能
通过调用init_数组&array;在main中成功创建_数组并调用print_数组&array;之后,我得到了预期的输出。在这里显示太无聊了。

这段代码是基于您从我这里得到的以及您在上面编写的内容编写的,看起来工作正常。请注意和PRIXPTR的使用以及uintptr的转换。它避免了对指针大小的假设,并且在32位和64位系统上同样有效,尽管%.8意味着您在32位编译中可以获得完整的8位十六进制值,在这个特定的64位平台上,最多可以得到16个十六进制值中的12个

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

typedef struct
{
    int    height;
    int    width;
    int    bottom;
    unsigned int **dat_ptr;  // Double pointer, not triple pointer
} array_info;

static void create_array(array_info *A)
{
    unsigned int **array = malloc(sizeof(*array) * A->height);
    printf("array (%zu) = 0x%.8" PRIXPTR "\n",
           sizeof(*array) * A->height, (uintptr_t)array);
    for (int i = 0; i < A->height; ++i)
    {
        array[i] = malloc(sizeof(**array) * A->width);
        printf("array[%d] (%zu) = 0x%.8" PRIXPTR "\n",
               i, sizeof(**array) * A->width, (uintptr_t)array[i]);
    }
    A->dat_ptr = array;
}

static void free_array(array_info *A)
{
    int i;
    for(i = 0; i < (A->height); ++i)
    {
        printf("About to free %d: 0x%.8" PRIXPTR "\n",
               i, (uintptr_t)A->dat_ptr[i]);
        free(A->dat_ptr[i]);
    }
    printf("About to free: 0x%.8" PRIXPTR "\n", (uintptr_t)A->dat_ptr);
    free(A->dat_ptr);
}

int main(void)
{
    array_info array = { .height = 5, .width = 10, .dat_ptr = 0 };
    create_array(&array);
    if (array.dat_ptr == 0)
    {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    free_array(&array);
    puts("OK");
    return(0);
}
我在这台机器上没有valgrind,但是分配和释放的地址可以被肉眼看到,表明没有明显的问题。巧合的是,我调整了数组的大小,使它们在64位机器上都是40字节

后续问题 你还在用你的数据做什么? 您分配的阵列有多大? 你确定没有遇到算术溢出吗? 在Mac OS X 10.8.2和GCC/Clang的XCode版本上进行测试:

i686-apple-darwin11-llvm-gcc-4.2 gcc 4.2.1基于苹果公司构建5658 llvm构建2336.11.00

阵列设置和打印功能
通过调用init_数组&array;在main中成功创建_数组并调用print_数组&array;之后,我得到了预期的输出。这太无聊了,无法在这里显示。

在调试时尝试过它,但它的表现方式相同:如果您更改了malloc函数,我在代码段中看不到任何其他错误。此错误通常由某种数组越界异常生成。可能错误不在此代码段中。我建议发布您的计算代码。我昨天尝试更改malloc部分,但没有任何效果。现在我知道原因了:再次感谢您建议在第一次访问未分配内存时可能不会生成异常:在调试时尝试了它,但其行为方式相同:如果更改了malloc函数,我在代码段中没有看到任何其他错误。此错误通常由某种数组越界异常生成。可能错误不在此代码段中。我建议发布您的计算代码。我昨天尝试更改malloc部分,但没有任何效果。现在我知道原因了:再次感谢您建议在首次访问未分配内存时可能不会生成异常:听起来像是您在创建数组和释放数组调用之间进行的“计算”注销了其中一个数组的结尾,因此当y>=A->width或y<0时,您存储在A->dat\u ptr[x][y]中。使用内存检查器valgrind,或者手动为每个数组访问添加边界检查。听起来像是在创建数组和释放数组调用之间进行的“计算”注销了其中一个数组的结尾,因此当y>=a->width或y<0时,存储在a->dat\u ptr[x][y]中。或者使用内存检查
或者对每个数组访问手动添加边界检查。您还对数据做了什么?我正在做一个简单的四点法解一组偏微分方程。基本上,当前阵列中的每个点都等于前一个fi中四个相邻点的平均值,j=0/25*fi+1,j+fi-1,j+fi,j+1+fi,j-1。用这种数学方法,我现在还远远没有溢出任何最大值。您分配的数组有多大?现在,当我调试时,它们将是大约10x10。然而,该程序的思想是找到10x10网格的解决方案,然后通过在已建立的节点之间使用线性插值将其应用于100x100,然后使用这些解决方案线性插值1000x1000网格,依此类推,最大值可能永远不会达到10000x1000。这种方法大大减少了每个解决方案的迭代次数。我以前使用数组,但当我试图在计算机上寻址1000x1000个数组时遇到了限制,所以我决定切换到mallocs。此外,它允许我使用单独的内存块,这样我就不必找到超过10kB的连续字符串。程序的最终输出是某个结构的电容和内部场分布的漂亮图片:1000 x 1000 x SizeFunSigned int仅为4MB;这并不离谱。在大多数机器上,100次并不是一个大问题。我假设你的计算不是0/25*。。。但0.25*。。。;否则,你要用非常困难的方法计算零。我还假设,在处理矩阵边缘的单元格时,要小心确保既不读取也不特别写入超出范围的索引。出界阅读通常不好,但通常不会让你崩溃。写越界是非常糟糕的。您是否将角单元格的节点平均为2个,边缘单元格的节点平均为3个?我现在也看到了您对该问题的更新,它给出了解决方案,并且确实与访问“超出边界”的元素有关。做得好。我很高兴你发现了你的问题,同时我也帮了你。你还在用你的数据做什么?我正在做一个简单的四点法解一组偏微分方程。基本上,当前阵列中的每个点都等于前一个fi中四个相邻点的平均值,j=0/25*fi+1,j+fi-1,j+fi,j+1+fi,j-1。用这种数学方法,我现在还远远没有溢出任何最大值。您分配的数组有多大?现在,当我调试时,它们将是大约10x10。然而,该程序的思想是找到10x10网格的解决方案,然后通过在已建立的节点之间使用线性插值将其应用于100x100,然后使用这些解决方案线性插值1000x1000网格,依此类推,最大值可能永远不会达到10000x1000。这种方法大大减少了每个解决方案的迭代次数。我以前使用数组,但当我试图在计算机上寻址1000x1000个数组时遇到了限制,所以我决定切换到mallocs。此外,它允许我使用单独的内存块,这样我就不必找到超过10kB的连续字符串。程序的最终输出是某个结构的电容和内部场分布的漂亮图片:1000 x 1000 x SizeFunSigned int仅为4MB;这并不离谱。在大多数机器上,100次并不是一个大问题。我假设你的计算不是0/25*。。。但0.25*。。。;否则,你要用非常困难的方法计算零。我还假设,在处理矩阵边缘的单元格时,要小心确保既不读取也不特别写入超出范围的索引。出界阅读通常不好,但通常不会让你崩溃。写越界是非常糟糕的。您是否将角单元格的节点平均为2个,边缘单元格的节点平均为3个?我现在也看到了您对该问题的更新,它给出了解决方案,并且确实与访问“超出边界”的元素有关。做得好。我很高兴你发现了你的问题,同时我也帮了你。
array (40) = 0x7FAFB3C03980
array[0] (40) = 0x7FAFB3C039B0
array[1] (40) = 0x7FAFB3C039E0
array[2] (40) = 0x7FAFB3C03A10
array[3] (40) = 0x7FAFB3C03A40
array[4] (40) = 0x7FAFB3C03A70
About to free 0: 0x7FAFB3C039B0
About to free 1: 0x7FAFB3C039E0
About to free 2: 0x7FAFB3C03A10
About to free 3: 0x7FAFB3C03A40
About to free 4: 0x7FAFB3C03A70
About to free: 0x7FAFB3C03980
OK
static void init_array(array_info *A)
{
    unsigned int ctr = 0;
    printf("D       = 0x%.8" PRIXPTR "\n", (uintptr_t)A->dat_ptr);
    for (int i = 0; i < A->height; i++)
    {
        printf("D[%d]    = 0x%.8" PRIXPTR "\n",i, (uintptr_t)A->dat_ptr[i]);
        for (int j = 0; j < A->width; j++)
        {
            printf("D[%d][%d] = 0x%.8" PRIXPTR " (%u)\n",
                   i, j, (uintptr_t)&A->dat_ptr[i][j], ctr);
            A->dat_ptr[i][j] = ctr;
            ctr += 7;
        }
    }
}

static void print_array(array_info *A)
{
    printf("D       = 0x%.8" PRIXPTR "\n", (uintptr_t)A->dat_ptr);
    for (int i = 0; i < A->height; i++)
    {
        printf("D[%d]    = 0x%.8" PRIXPTR "\n",i, (uintptr_t)A->dat_ptr[i]);
        for (int j = 0; j < A->width; j++)
        {
            printf("D[%d][%d] = 0x%.8" PRIXPTR " (%u)\n",
                   i, j, (uintptr_t)&A->dat_ptr[i][j], A->dat_ptr[i][j]);
        }
    }
}