我随机创建了两个矩阵A0和A1。之后,我将这两个矩阵复制到A01矩阵,例如
[A0 | 0 ]
[0 | A1]
最后,我删除了他们的记忆。但是,我只运行了3-5次,之后,程序检测到错误,如
我正在使用visual studio 2015.我的代码会发生什么?删除指针矩阵是错误的吗?
这是我的完整代码
#include <iostream>
#include <stdlib.h>
#include <time.h> /* time */
#define random(x) (rand()%x)
typedef unsigned char U8;
typedef unsigned int U32;
void create_and_delete_matrix()
{
U32 M0,M1,M01;
U32 m_L0,m_L1,m_L01;
U32 range = 20;
M0 = random(range) + 1;
m_L0 = random(range) + 1;
M1 = random(range) + 1;
m_L1 = random(range) + 1;
M01 = M0 + M1;
m_L01 = m_L0 + m_L1;
U8** A0 = new U8*[M0];
U8** A1 = new U8*[M1];
U8** A01 = new U8*[M01];
//***********For A0***********//
for (U32 i = 0; i < M0; ++i){
A0[i] = new U8[m_L0];
memset(A0[i], 0, m_L0*sizeof(U8));
}
//***********For A1***********//
for (U32 i = 0; i < M1; ++i) {
A1[i] = new U8[m_L1];
memset(A1[i], 0, m_L1*sizeof(U8));
}
//***********For A01***********//
for (U32 i = 0; i < M01; ++i) {
A01[i] = new U8[m_L01];
memset(A01[i], 0, m_L01*sizeof(U8));
}
//***********Set random data A0 and A1***********//
for (U32 i = 0; i < M0; ++i) {
for (U32 j = 0; j < m_L0; ++j) {
A0[i][j] = random(2);
printf("%d ", A0[i][j]);
}
printf("\n");
}
for (U32 i = 0; i < M1; ++i) {
for (U32 j = 0; j < m_L1; ++j) {
A1[i][j] = random(2);
printf("%d ", A1[i][j]);
}
printf("\n");
}
//***********Copy A0 and A1 to A01 ***********//
//***********--------------------- ***********//
//***********------[A0 | 0 ]-------***********//
//***********------[0 | A1]-------***********//
//***********--------------------- ***********//
for (U32 i = 0; i < M0; ++i){
//A0 to A01
memcpy(A01[i] + m_L0, A0[i], m_L0 * sizeof(U8));
}
for (U32 i = 0; i < M1; ++i){
// A1 to A01
memcpy(A01[i + M0] + m_L0, A1[i], m_L1 * sizeof(U8));
}
//**********Print result of A01**********//
for (U32 i = 0; i < M01; ++i) {
for (U32 j = 0; j < m_L01; ++j) {
printf("%d ", A01[i][j]);
}
printf("\n");
}
//free A0, A1, A01 matrix
for (U32 i = 0; i < M0; ++i){
if (i < m_L0){
delete[] A0[i];
A0[i] = NULL;
}
}
delete[] A0;
A0 = NULL;
for (U32 i = 0; i < M1; ++i) {
if (i < m_L1) {
delete[] A1[i];
A1[i] = NULL;
}
}
delete[] A1;
A1 = NULL;
for (U32 i = 0; i < M01; ++i) {
if (i < m_L01) {
delete[] A01[i];
A01[i] = NULL;
}
}
delete[] A01;
A01 = NULL;
}
int main(int argc, char **argv) {
unsigned int time_ui = static_cast<unsigned int>(time(NULL));
srand(time_ui);
for (U32 iter = 0; iter < 100; iter++){
create_and_delete_matrix();
}
return 0;
}
我还在Ubuntu中使用g ++进行了测试,错误是
*** Error in `main': free(): invalid next size (fast): 0x0000000001a58600 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7850e)[0x7ff6e22d750e]
/lib64/libc.so.6(cfree+0x5b5)[0x7ff6e22e3165]
main[0x40107b]
main[0x401105]
/lib64/libc.so.6(__libc_start_main+0xf0)[0x7ff6e227efe0]
main[0x400939]
======= Memory map: ========
00400000-00402000 r-xp 00000000 fd:198 59464901 /home/cg/root/main
00601000-00602000 r--p 00001000 fd:198 59464901 /home/cg/root/main
00602000-00603000 rw-p 00002000 fd:198 59464901 /home/cg/root/main
答案 0 :(得分:4)
由于memcpy
中的重叠/错误范围导致的未定义行为。
请注意,您的代码或多或少是C,而不是C ++。如果您使用std::vector
,则可以让您的生活更轻松,例如:
typedef std::vector<U8> vector_u8_t;
typedef std::vector<vector_u8_t> matrix_u8_t;
matrix_u8_t A0(M0, vector_u8_t(m_L0, 0)); // (*)
标记的行为您完成矩阵的所有分配和初始化(除了随机值),您也不必担心以后释放内存。
它仍然不是一个合适的矩阵类,但它需要你承担一些责任。
答案 1 :(得分:2)
问题在这里
for (U32 i = 0; i < M0; ++i){
//A0 to A01
memcpy(A01[i] + m_L0, A0[i], m_L0 * sizeof(U8));
}
for (U32 i = 0; i < M1; ++i){
// A1 to A01
memcpy(A01[i + M0] + m_L0, A1[i], m_L1 * sizeof(U8));
}
应该是
for (U32 i = 0; i < M0; ++i){
//A0 to A01
memcpy(A01[i], A0[i], m_L0 * sizeof(U8));
}
for (U32 i = 0; i < M1; ++i){
// A1 to A01
//After m_L0 elements
memcpy(A01[i] + m_L0, A1[i], m_L1 * sizeof(U8));
}
或者你可以复制元素,这将使它更具可读性。
此外,这里
for (U32 i = 0; i < M0; ++i){
A0[i] = new U8[m_L0];
}
for (U32 i = 0; i < M0; ++i){
A0[i] = new U8[m_L0];
memset(A0[i], 0, m_L0*sizeof(U8));
}
//***********For A1***********//
for (U32 i = 0; i < M1; ++i){
A1[i] = new U8[m_L1];
}
for (U32 i = 0; i < M1; ++i) {
A1[i] = new U8[m_L1];
memset(A1[i], 0, m_L1*sizeof(U8));
}
您正在创建内存泄漏。不需要第一个循环。相反,如果可能的话,使用初始化程序初始化为0。
为了避免在此处进行内存管理,您可以将std::vector
与reserve
一起使用。
修改强> 免费,它必须是您的分配的补充:
for (U32 i = 0; i < M1; ++i) {
delete [] A0[i];
}
delete [] A0;