结构的内存分配问题
Memory Allocation Problems with structure
为什么提供的代码在下一行崩溃?
data *fillA = (data*)calloc(matrixa->nzmax, sizeof(data));
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include <time.h>
using namespace std;
struct csr
{
int rows;
int cols;
int nzmax;
int *rowPtr;
int *colInd;
double *values;
};
struct data
{
int entry;
int index;
};
bool descend(const data &a, const data &b)
{
return a.entry > b.entry;
}
static bool ascend(const data &a, const data &b)
{
return a.entry < b.entry;
}
void csrtranspose(struct csr *matrixa)
{
int i, j, counter;
double *tArray = NULL;
data *fillA = (data*)calloc(matrixa->nzmax, sizeof(data));//fails here
for (int i = 0; i < matrixa->nzmax; i++)
{
fillA[i].entry = matrixa->colInd[i];
fillA[i].index = i;
}
sort(fillA, fillA + matrixa->nzmax, ascend);
tArray = (double*)calloc(matrixa->nzmax, sizeof(double));
for (int i = 0; i < matrixa->nzmax; i++)
{
tArray[i] = matrixa->values[i];
}
for (int i = 0; i < matrixa->nzmax; i++)
{
matrixa->colInd[i] = fillA[i].entry;
matrixa->values[i] = tArray[fillA[i].index];
}
free(tArray);
free(fillA);
}
int main()
{
int i;
struct data *total = 0;
struct csr *s = 0;
int nrows = 6, ncols = 5, counter = 0, nzmax = 10, rows = 3, cols = 5;
double values[10] = {0.2135, 0.8648, 7, 0.3446, 0.1429, 6, 0.02311, 0.3599, 0.0866, 8 };
int rowPtr[4] = { 0, 3, 6, 10 };
int colInd[10] = { 0, 2, 4, 1, 2, 3, 0, 1, 2, 4 };
s = (struct csr*) calloc(1, sizeof(struct csr));
s->rows = rows;
s->cols = cols;
s->nzmax = nzmax;
s->rowPtr = (int*)calloc(s->rows + 1, sizeof(int));
s->colInd = (int*)calloc(s->nzmax, sizeof(int));
s->values = (double*)calloc(s->nzmax, sizeof(int));
for (i = 0; i<10; i++)
{
s->colInd[i] = colInd[i];
s->values[i] = values[i];
if (i <= s->rows)
{
s->rowPtr[i] = rowPtr[i];
}
}
csrtranspose(s);
getchar();
}
它在那里崩溃的原因是因为内存已经被以前的错误代码破坏了。所以,问题不在崩溃的地方,问题出在更早执行的代码中。
具体来说,这一行:
s->values = (double*)calloc(s->nzmax, sizeof(int));
分配双精度,但使用 sizeof(int)
,因此它没有分配足够的内存。
编辑
建议:
正如其他人已经指出的那样,在使用 C++ 时,使用 new
运算符而不是 C 风格的内存分配。它将使您免于很多问题。
如果你坚持使用 C 风格的分配,永远不要使用 p = (type*)malloc( sizeof(type) )
,总是使用 p = (type*)malloc( sizeof( *p ) )
。当您犯下为错误类型分配内存的常见错误时,这至少会使其更加明显。
行 (double*)calloc(s->nzmax, sizeof(int));
本身就是切换到 C++ 分配的一个很好的理由,即使您复制和粘贴也不可能犯这个错误。
您分配的内存太少并且越界写入。
因为你所有的大小在编译时都是已知的,所以你根本不需要动态分配。
为什么提供的代码在下一行崩溃?
data *fillA = (data*)calloc(matrixa->nzmax, sizeof(data));
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include <time.h>
using namespace std;
struct csr
{
int rows;
int cols;
int nzmax;
int *rowPtr;
int *colInd;
double *values;
};
struct data
{
int entry;
int index;
};
bool descend(const data &a, const data &b)
{
return a.entry > b.entry;
}
static bool ascend(const data &a, const data &b)
{
return a.entry < b.entry;
}
void csrtranspose(struct csr *matrixa)
{
int i, j, counter;
double *tArray = NULL;
data *fillA = (data*)calloc(matrixa->nzmax, sizeof(data));//fails here
for (int i = 0; i < matrixa->nzmax; i++)
{
fillA[i].entry = matrixa->colInd[i];
fillA[i].index = i;
}
sort(fillA, fillA + matrixa->nzmax, ascend);
tArray = (double*)calloc(matrixa->nzmax, sizeof(double));
for (int i = 0; i < matrixa->nzmax; i++)
{
tArray[i] = matrixa->values[i];
}
for (int i = 0; i < matrixa->nzmax; i++)
{
matrixa->colInd[i] = fillA[i].entry;
matrixa->values[i] = tArray[fillA[i].index];
}
free(tArray);
free(fillA);
}
int main()
{
int i;
struct data *total = 0;
struct csr *s = 0;
int nrows = 6, ncols = 5, counter = 0, nzmax = 10, rows = 3, cols = 5;
double values[10] = {0.2135, 0.8648, 7, 0.3446, 0.1429, 6, 0.02311, 0.3599, 0.0866, 8 };
int rowPtr[4] = { 0, 3, 6, 10 };
int colInd[10] = { 0, 2, 4, 1, 2, 3, 0, 1, 2, 4 };
s = (struct csr*) calloc(1, sizeof(struct csr));
s->rows = rows;
s->cols = cols;
s->nzmax = nzmax;
s->rowPtr = (int*)calloc(s->rows + 1, sizeof(int));
s->colInd = (int*)calloc(s->nzmax, sizeof(int));
s->values = (double*)calloc(s->nzmax, sizeof(int));
for (i = 0; i<10; i++)
{
s->colInd[i] = colInd[i];
s->values[i] = values[i];
if (i <= s->rows)
{
s->rowPtr[i] = rowPtr[i];
}
}
csrtranspose(s);
getchar();
}
它在那里崩溃的原因是因为内存已经被以前的错误代码破坏了。所以,问题不在崩溃的地方,问题出在更早执行的代码中。
具体来说,这一行:
s->values = (double*)calloc(s->nzmax, sizeof(int));
分配双精度,但使用 sizeof(int)
,因此它没有分配足够的内存。
编辑
建议:
正如其他人已经指出的那样,在使用 C++ 时,使用
new
运算符而不是 C 风格的内存分配。它将使您免于很多问题。如果你坚持使用 C 风格的分配,永远不要使用
p = (type*)malloc( sizeof(type) )
,总是使用p = (type*)malloc( sizeof( *p ) )
。当您犯下为错误类型分配内存的常见错误时,这至少会使其更加明显。
行 (double*)calloc(s->nzmax, sizeof(int));
本身就是切换到 C++ 分配的一个很好的理由,即使您复制和粘贴也不可能犯这个错误。
您分配的内存太少并且越界写入。
因为你所有的大小在编译时都是已知的,所以你根本不需要动态分配。