在函数内部使用malloc()后“写入访问冲突”

时间:2019-04-01 12:07:24

标签: c exception multidimensional-array struct malloc

问题

我有2D矩阵的自定义结构。我在函数内部使用此结构初始化一个2D矩阵,其中每个元素值均设置为0。我还有另一个函数将矩阵打印到终端(出于调试目的)。

当我在main.c内编写结构和函数时,它们就起作用了。问题是,当我将它们放在单独的文件中并从该文件中调用它们时,出现运行时错误:Exception thrown: write access violation

在我的程序中,我有3个文件:main.cmy_lib.hmy_lib.c。该结构存储在my_lib.h内部,函数位于my_lib.c中。在main.h

内部

我正在使用Windows 10和Visual Studio 2017 v15.9.10中的编码

输出

程序可以编译,但会给出运行时错误Exception thrown: write access violation enter image description here

编辑:

好吧,这似乎是我自己的错。

实际上,我试图在我的工作计算机上运行此代码。我已经在运行main.cmy_lib.hmy_lib.c版本的个人计算机上编写了原始代码。然后,我复制了正在使用的文件夹,并尝试在工作计算机上继续。我的两台计算机都在Windows 10操作系统上运行,并且都具有相同版本的VS 2017。

在我的个人计算机上,解决方案资源管理器如下:

enter image description here

但是在我的工作计算机上,解决方案打开为:

enter image description here

两台计算机上的所有内容(包括文件夹层次结构)都相同。看来,复制项目文件夹不是一个好主意。

当我在工作计算机上创建一个新的C项目并手动添加my_lib.cmy_lib.h时,一切正常。

但是我仍然很好奇为什么会出现Exception错误...以及如何在不使用VS创建新项目的情况下解决复制问题?

代码

仅仅是main.c(Works)

main.c

#include <stdio.h>

typedef struct Matrix {
    int rows; // number of rows
    int cols; // number of columns
    double** data; // a pointer to an array of n_rows pointers to rows
}Matrix;

Matrix* make_matrix(int n_rows, int n_cols);
void print_matrix(Matrix* m);

int main() {

    Matrix* m1 = make_matrix(2, 5);

    print_matrix(m1);

    return 0;
}


// CREATE A MATRIX WITH N_ROWS AND N_COLUMNS AND INITIALIZE EACH VALUE AS 0
Matrix* make_matrix(int n_rows, int n_cols) {
    Matrix* matrix = malloc(sizeof(Matrix));
    matrix->rows = n_rows;
    matrix->cols = n_cols;
    double** data = malloc(sizeof(double*) * n_rows);
    for (int x = 0; x < n_rows; x++) {
        data[x] = calloc(n_cols, sizeof(double));
    }
    matrix->data = data;
    return matrix;
}

// PRINT GIVEN MATRIX TO COMMAND LINE
void print_matrix(Matrix* m) {
    for (int x = 0; x < m->rows; x++) {
        for (int y = 0; y < m->cols; y++) {
            printf("%f", m->data[x][y]);
            printf("|");
        }
        printf("\n");
    }
}

main.c和单独文件中的功能(引发异常)

main.c

#include "my_lib.h"
int main(){
        // Create a 2 by 5 matrix & then print it to terminal
        Matrix* m1 = make_matrix(2, 5);
        print_matrix(m1);
        return 0;
}

my_lib.h

#pragma once

// Our custom 2D matrix struct
typedef struct Matrix {
    int rows; // number of rows
    int cols; // number of columns
    double** data; // a pointer to an array of n_rows pointers to rows
}Matrix;

Matrix* make_matrix(int n_rows, int n_cols);
void print_matrix(Matrix* m);

my_lib.c

#include "my_lib.h"
#include <stdio.h>

// CREATE A MATRIX WITH N_ROWS AND N_COLUMNS AND INITIALIZE EACH VALUE AS 0
Matrix* make_matrix(int n_rows, int n_cols) {
    Matrix* matrix = malloc(sizeof(Matrix));
    matrix->rows = n_rows;
    matrix->cols = n_cols;
    double** data = malloc(sizeof(double*) * n_rows);
    for (int x = 0; x < n_rows; x++) {
        data[x] = calloc(n_cols, sizeof(double));
    }
    matrix->data = data;
    return matrix;
}

// PRINT GIVEN MATRIX TO COMMAND LINE
void print_matrix(Matrix* m) {
    for (int x = 0; x < m->rows; x++) {
        for (int y = 0; y < m->cols; y++) {
            printf("%f", m->data[x][y]);
            printf("|");
        }
        printf("\n");
    }
}

1 个答案:

答案 0 :(得分:2)

发生崩溃的原因与项目中只有一个或两个.c文件完全无关,而是因为您忘记在<stdlib.h>中包含my_lib.c

这将触发以下触发警告:

  

my_lib.c(8):警告C4013:'malloc'未定义;假设外部   返回int
my_lib.c(13):警告C4013:'calloc'未定义;   假设extern返回int
my_lib.c(13):警告C4047:'=':   “ double *”的间接级别与“ int”不同
  my_lib.c(8):警告C4047:“正在初始化”:“矩阵*”不同   来自'int'的间接级别
my_lib.c(11):警告C4047:   'initializing':'double **'的间接级别与   'int'

由于int的大小与指针的大小相同,因此您无需使用32位构建。

另一方面,如果您将程序构建为64位程序,则警告变得非常相关,因为现在指针的宽度为64位,但是编译器假定malloc等返回int一切都搞砸了。

实际上,这些警告应视为错误。

在这里决定要构建32位还是64位:

enter image description here

#include <stdlib.h>的此处添加my_lib.c

#include "my_lib.h"
#include <stdlib.h>   // <<<<<<<<<<<<<
#include <stdio.h>


// CREATE A MATRIX WITH N_ROWS AND N_COLUMNS AND INITIALIZE EACH VALUE AS 0
Matrix* make_matrix(int n_rows, int n_cols) {
  Matrix* matrix = malloc(sizeof(Matrix));
  ...