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

Ogu*_*bek 4 c malloc struct exception multidimensional-array

问题

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

当我在 中编写结构和函数时main.c,它们就可以工作。问题是当我将它们放在一个单独的文件中并从该文件调用它们时,我收到运行时错误:Exception thrown: write access violation

在我的程序中,我有 3 个文件:main.c, my_lib.h, my_lib.c. 结构体存储在里面my_lib.h,函数在my_lib.c. 里面main.h

我正在使用 Windows 10 并在 Visual Studio 2017 v15.9.10 中进行编码

输出

程序可以编译但出现运行时错误Exception thrown: write access violation 在此输入图像描述

编辑:

好吧,看来这件事的发生是我自己的错。

实际上,我试图在我的工作计算机上运行这段代码。我已经在我的个人计算机上编写了原始代码,其中main.c, my_lib.h&my_lib.c版本可以正常工作。然后我复制了我正在处理的文件夹并尝试在我的工作计算机上继续。我的两台电脑都运行 Windows 10 操作系统,并且都有相同版本的 VS 2017。

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

在此输入图像描述

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

在此输入图像描述

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

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

但我仍然很好奇为什么我收到异常错误...以及如何在不创建 VS 中创建新项目的情况下纠正这个复制问题?

代码

只是 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

Jab*_*cky 7

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

这会触发以下警告:

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

您可以在 32 位版本上使用它,因为 的大小int与指针的大小相同。

另一方面,如果您将程序构建为 64 位程序,则警告变得非常相关,因为现在指针是 64 位宽,但由于编译器假设mallocetc. 返回ints (32 位值),所以一切都会变得混乱。

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

您可以在此处决定是否需要 32 位或 64 位版本:

在此输入图像描述

添加#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));
  ...
Run Code Online (Sandbox Code Playgroud)