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 中创建新项目的情况下纠正这个复制问题?
主程序
#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)
主程序
#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)
崩溃的原因与项目中有一两个 .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)