简体   繁体   English

尝试在 C 中复制 4 个字符结构的二维数组时出现 memcpy 错误分段错误

[英]memcpy error segmentation fault while trying to copy 2D array of 4 char structure in C

Hey I'm trying to copy an array of SDL_Color created from an image in another one.嘿,我正在尝试复制从另一个图像中创建的 SDL_Color 数组。 But for some images, I get:但是对于某些图像,我得到:

Process finished with exit code -1073741819 (0xC0000005)进程以退出代码 -1073741819 (0xC0000005) 结束

It happens for an image of 20 x 20 pixels but it works well for a 50 x 50 one... here is my code:它发生在 20 x 20 像素的图像上,但它适用于 50 x 50 的图像......这是我的代码:

FILE *debugFile = fopen("C:\\Users\\Clement\\Documents\\coding\\ImageOfCLife\\debug.txt", "w+");
int imgWidth, imgHeight, channels;
unsigned char *img = stbi_load("C:\\Users\\Clement\\Documents\\coding\\ImageOfCLife\\star.jpg", &imgWidth,
                               &imgHeight, &channels, 0);
fprintf(debugFile, "Loaded image with a width of %dpx, a imgHeight of %dpx and %d channels\n", imgWidth, imgHeight, channels);
dRulesLen = sizeof(deathRules);
bRulesLen = sizeof(birthRules);
if (img == NULL) {
    fprintf(debugFile, "Error in loading the image\n");
    exit(3);
}

int ch, pix;
SDL_Color **stateMatrix1 = (SDL_Color **) malloc(imgHeight * sizeof(SDL_Color*));
if (stateMatrix1 == NULL) {
    fprintf(debugFile,"Unable to allocate memory\n");
    exit(1);
}
for (int i = 0; i < imgHeight; ++i) {
    stateMatrix1[i] = (SDL_Color *) malloc(imgWidth * sizeof(SDL_Color));
}
for (ch = 0; ch < imgHeight; ch++) {
    printf("{");
    for (pix = 0; pix < imgWidth; pix++) {
        unsigned bytePerSDL_Color = channels;
        unsigned char *SDL_ColorOffset = img + (pix + imgHeight * ch) * bytePerSDL_Color;
        SDL_Color p = initSDL_Color(SDL_ColorOffset);
        stateMatrix1[ch][pix] = p;
        printSDL_Color(p);
        printf(", ");
    }
    printf("}\n");
}
SDL_Color stateMatrix2[imgHeight][imgWidth];
memcpy(stateMatrix2, stateMatrix1, imgWidth*imgHeight*sizeof(SDL_Color)); 

the last line is the problem according to the debugger I tried最后一行是根据我试过的调试器的问题

memcpy(stateMatrix2, stateMatrix1, sizeof(stateMatrix2)) memcpy(stateMatrix2, stateMatrix1, sizeof(stateMatrix2))

too but I get the same result.也是,但我得到了相同的结果。

I work on windows 10 with minGW and Clion.我与 minGW 和 Clion 一起在 windows 10 上工作。 I hope you can help me with this issue.我希望你能帮助我解决这个问题。

I also tried to replace SDL_Color stateMatrix2[imgHeight][imgWidth];我也尝试替换SDL_Color stateMatrix2[imgHeight][imgWidth]; by:经过:

    SDL_Color **stateMatrix2 = (SDL_Color **) malloc(imgHeight * sizeof(SDL_Color*));
if (stateMatrix2 == NULL) {
    fprintf(debugFile,"Unable to allocate memory\n");
    exit(1);
}
for (int i = 0; i < imgHeight; ++i) {
    stateMatrix2[i] = (SDL_Color *) malloc(imgWidth * sizeof(SDL_Color));
}

but i got the same issue.但我遇到了同样的问题。

I forgot to say it but I want ant to be able to use both stateMatrix as parameter of a function.我忘了说,但我希望 ant 能够使用两个 stateMatrix 作为 function 的参数。

To fix it I used the Olaf solution explained below: I kept:为了解决这个问题,我使用了下面解释的 Olaf 解决方案:我保留了:

SDL_Color **stateMatrix1 = (SDL_Color **) malloc(imgHeight * sizeof(SDL_Color*));
if (stateMatrix1 == NULL) {
    fprintf(debugFile,"Unable to allocate memory\n");
    exit(1);
}
for (int i = 0; i < imgHeight; ++i) {
    stateMatrix1[i] = (SDL_Color *) malloc(imgWidth * sizeof(SDL_Color));
}

to allocate memory to both matrix and used:将 memory 分配给矩阵和使用:

for (int i = 0; i < imgHeight; ++i) {
memcpy(stateMatrix2[i], stateMatrix1[i], imgWidth * sizeof(SDL_Color));
}

to perform the copy.执行复制。 I also verified that the two matrix were'nt linked and there were no problem.我还验证了这两个矩阵没有链接,没有问题。

When copying复印时

memcpy(stateMatrix2, stateMatrix1, imgWidth * imgHeight * sizeof(SDL_Color));

you will go beyond the end of stateMatrix1 , which is not imgWidth * imgHeight * sizeof(SDL_Color) , but imgHeight * sizeof(SDL_Color*) .您将 go 超出stateMatrix1的末尾,这不是imgWidth * imgHeight * sizeof(SDL_Color) ,而是imgHeight * sizeof(SDL_Color*)


Copying in a loop from stateMatrix1 to stateMatrix2 is one way to solve thisstateMatrix1循环复制到stateMatrix2是解决此问题的一种方法

for (int i = 0; i < imgHeight; ++i) {
    memcpy(stateMatrix2[i], stateMatrix1[i], imgWidth * sizeof(SDL_Color));
}

Another would be making both matrices the same type.另一种方法是将两个矩阵设为同一类型。 But when allocating stateMatrix2 as但是当将stateMatrix2分配为

SDL_Color **stateMatrix2 = (SDL_Color **) malloc(imgHeight * sizeof(SDL_Color*));

and later use the same memcpy as above, you will still go beyond stateMatrix1 and now also beyond the end of stateMatrix2 .稍后使用与上面相同的memcpy ,您仍然会 go 超出stateMatrix1 现在也超出stateMatrix2的末尾。


The correct way to copy (but still wrong for another reason) would be正确的复制方法(但由于另一个原因仍然是错误的)是

memcpy(stateMatrix2, stateMatrix1, sizeof(*stateMatrix1));

This is correct in terms of size, but still wrong, because it copies the pointers of stateMatrix1 to stateMatrix2 .这在大小方面是正确的,但仍然是错误的,因为它将stateMatrix1指针复制到stateMatrix2 This has two effects这有两个效果

  1. When you initialized stateMatrix2 with its own pointers, there will be memory leaks.当您使用自己的指针初始化stateMatrix2时,将会出现 memory 泄漏。
  2. Now both matrices point to the same memory, which means changing one, will change the other too.现在两个矩阵都指向同一个 memory,这意味着改变一个,也会改变另一个。

Your error is explained in comments.您的错误在评论中解释。 You could fix it by allocating a contiguous block of memory for your matrix instead of many blocks as you did.您可以通过为您的矩阵分配一个连续的 memory 块而不是像您所做的许多块来修复它。 This way of doing is even simpler, for allocation, deallocation and copy (since you can then use a single call to memcpy):对于分配、解除分配和复制,这种做法更加简单(因为您可以使用一次对 memcpy 的调用):

#include <stdio.h>
#include <stdlib.h>

struct SDL_Color {
    unsigned char rgba[4];
};

int main() {
    int ch, pix;
    int imgWidth = 100;
    int imgHeight = 100;
    struct SDL_Color (*stateMatrix1)[imgWidth][imgHeight] = malloc(sizeof(*stateMatrix1));
    if (*stateMatrix1 == NULL) {
        printf("Unable to allocate memory\n");
    } else {
        free(*stateMatrix1);
        printf("Success\n");
    }
    return 0;
}

You just need to take care of dereferencing the pointer to the matrix each time you use it.您只需要在每次使用它时取消对矩阵的指针的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM