memcpy() 给我段错误

Posted

技术标签:

【中文标题】memcpy() 给我段错误【英文标题】:memcpy() giving me seg faults 【发布时间】:2016-06-11 04:41:45 【问题描述】:

当我不使用 memcopy 时,我的 OpenGL 程序编译并运行良好,但是当我在程序中使用此函数时,当我在编译后尝试运行程序时,它给我一个 seg 错误,它仍然在两者中编译情况,但是当我用这个函数编译程序时给了我 seg 错误,并且在 gdb 中检查时的 seg 错误并没有显示 memcpy 作为问题,而是一个初始化函数 init() 为我创建了 opengl 上下文,但是奇怪的事情是只有当我在程序中包含 memcpy 并编译它时才会发生这种情况,否则 init() 工作正常,我还在另一个文件中对其进行了测试以确认它可以自行工作

我不知道为什么会这样,我注意到这是因为 linux mint 升级了一些软件包后发生的,升级前程序运行良好

这是程序源代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/glew.h>
#include <GL/glx.h>

#include <time.h>
#include <math.h>

#include "glx2.c"
#include "renderBuffer.h"
#include "new.hpp"

#define WIDTH 1080 
#define HEIGHT 720

int main()

   init(WIDTH,HEIGHT);
   createShaders();

   char name[1][25];

   float returned[720][1080][2] = 0.0f;


   strcpy(name[0],"ryu2.bmp");

   GLuint frameBuffer = createFramebuffer(frameBuffer);

   GLuint renderTexture = createRenderTexture(renderTexture, WIDTH,HEIGHT);
   //GLuint depth_texture;

   //glGenTextures(1, &depth_texture);
   //glBindTexture(GL_TEXTURE_2D, depth_texture);
   //glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, 1080, 720);

   //glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,depth_texture, 0);

   glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,renderTexture,0);

   static const GLenum draw_buffers[] =  GL_COLOR_ATTACHMENT0 ;
   glDrawBuffers(1, draw_buffers);


   //bind framebuffer 
   glBindFramebuffer(GL_FRAMEBUFFER,frameBuffer);
   checkFramebuffer();

   GLfloat vertices[] =  

   //   
   //  X      Y                  U            V
   //triangle 1
     -1.0,       -1.0,          0.0,         0.0,
     -22.0/27.0, -1.0,          100.0/800.0, 0.0,
     -1.0,       -41.0/60.0,    0.0,         114.0/342.0,
     -22.0/27.0, -41.0/60.0,    100.0/800.0, 114.0/342.0;   


   GLuint vao1 = createVao();
   GLuint vbo1 = createVbo();

   glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  

   GLuint tex = createTexture(name[0]);

   //set up data format in opengl and save in vao
   glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0);
   glEnableVertexAttribArray(0);

   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (const GLvoid*)(2 * sizeof(GLfloat)));
   glEnableVertexAttribArray(1);


   bindObject(vao1, tex);

   glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
   glViewport(0,0, WIDTH,HEIGHT);

   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

   //////completed drawing to framebuffer original values 

   glBindFramebuffer(GL_FRAMEBUFFER,0);

   glBindTexture(GL_TEXTURE_2D, renderTexture);

   glGetTexImage(GL_TEXTURE_2D, 0,GL_RG,GL_FLOAT,(void *)&returned);

   float another[720][1080][2];

   memcpy((void *)another, (const void *)returned, sizeof(returned));
   //----------------------completed copying original values to array for all comparison

   int i = 0,j=0;

   //for(j=0; j<114;j++)
   //   for(i=0; i<100;i++)   
         //printf("%f %f\n",another[j][i][0], another[j][i][1]);
   //



   //from this point on there will be change and comparison

   //GLuint disp = glGetUniformLocation(shader_program, "disp");

   //glUniform2f(disp, 1.0/540,1.0/360);




   glXMakeCurrent( dpy, 0, 0 );
   glXDestroyContext( dpy, ctx );
   glXDestroyWindow(dpy, glxWin);
   XDestroyWindow( dpy, win );
   XFreeColormap( dpy, cmap );
   XCloseDisplay( dpy );

    return 0;


当我运行 gdb 时,这是它给出的问题,尽管当我注释掉 memcpy 时它工作正常并且没有给我任何 seg 错误

Program received signal SIGSEGV, Segmentation fault.
0x0000000000402876 in main () at untitled.cpp:22
22     init(WIDTH,HEIGHT);
(gdb) 

【问题讨论】:

这大约是 6 兆字节:float returned[720][1080][2] 然后你声明另外 6 兆字节,它可能超过了堆栈限制。尝试在堆上分配内存。 @BarmakShemirani 关于堆栈中分配的内存是正确的。也就是说,gbd 显示你的程序在 init() 函数内部崩溃了,对吗? @ichramm 那是正确的 sigsegv 在 init() 显示 seg 错误,但仅当包含 memcpy 时,我使用 init() 运行另一个文件而没有任何 memcpy,它工作正常,我还测试了 init()本身并且它工作正常 sig 错误仅在使用 memcpy() 时可能与覆盖堆栈有关,而堆栈必须覆盖 init() 上下文创建 我刚刚将堆上的数组声明为指针,现在可以正常工作 @BarmakShemirani 将您的答案放在问题部分的答案中,我会接受它作为正确答案 【参考方案1】:

@BarmakShemirani 指出的答案是 linux 的堆栈限制为 8mb,并且由于两个数组一起超过 12mb,因此会覆盖堆栈,因此为什么会出现问题,解决方案是写入 /使用 malloc() 分配给堆

【讨论】:

【参考方案2】:

@BarmakShemirani 关于堆栈限制是正确的。您还可以在代码中使用setrlimit. 增加堆栈限制(但最好不要在main function 中)。

【讨论】:

以上是关于memcpy() 给我段错误的主要内容,如果未能解决你的问题,请参考以下文章

关于c中memcpy的使用

memcpy在啥情况下会失败

memcpy在啥情况下会失败

使用 gdb 查找 memcpy 错误

__memcpy_ssse3() 分段错误

从共享内存段复制数据会导致客户端出现段错误(信号量和共享内存)