glTexImage2D读取超出缓冲区边界(iOS)

glTexImage2D读取超出缓冲区边界(iOS),ios,opengl-es,buffer-overflow,Ios,Opengl Es,Buffer Overflow,在下面的简单代码中,我将单通道数据加载到纹理。我使用glTexImage2D()和GL\u亮度(这是一种单通道格式)以及GL\u无符号字节,因此每像素应使用一个字节。我分配了一个大小等于像素数(2x2)的缓冲区,它代表输入像素数据(像素值对我们来说并不重要) 在启用地址清理器的情况下运行以下代码时,它在调用glTexImage2D()时检测到堆缓冲区溢出,表示它试图读取超出堆分配缓冲区边界的内容: #import <OpenGLES/ES2/gl.h> //... EAGLCon

在下面的简单代码中,我将单通道数据加载到纹理。我使用
glTexImage2D()
GL\u亮度
(这是一种单通道格式)以及
GL\u无符号字节
,因此每像素应使用一个字节。我分配了一个大小等于像素数(2x2)的缓冲区,它代表输入像素数据(像素值对我们来说并不重要)

在启用地址清理器的情况下运行以下代码时,它在调用
glTexImage2D()
时检测到堆缓冲区溢出,表示它试图读取超出堆分配缓冲区边界的内容:

#import <OpenGLES/ES2/gl.h>

//...

EAGLContext* context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:context];

GLsizei width = 2, height = 2;
void *data = malloc(width * height); // contents don't matter for now
glTexImage2D(GL_TEXTURE_2D,
             0,
             GL_LUMINANCE,
             width,
             height,
             0,
             GL_LUMINANCE,
             GL_UNSIGNED_BYTE,
             data);
#导入
//...
EAGLContext*上下文=[[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EagleContext setCurrentContext:context];
GLsizei宽度=2,高度=2;
void*data=malloc(宽*高);//内容暂时不重要
glTexImage2D(GL_纹理_2D,
0,
GL_亮度,
宽度,
高度,
0,
GL_亮度,
GL_无符号字节,
数据);
这是100%可复制的,并且发生在iOS模拟器和设备上。只有将缓冲区的大小增加到6,它才不会溢出(比预期的4大2)

1x1和4x4的尺寸似乎没有这个问题,但2x2和3x3有这个问题。这似乎有点武断


怎么了?

多亏了@genpfault的评论,我已经解决了这个问题

我需要将解包对齐设置为1:

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
具体而言,解包对齐方式确定每行开头的对齐方式。默认值为4。因为我的行没有任何特殊的对齐方式,并且行字节之间没有间隙,所以对齐方式应该是1


第一行将始终对齐,因为
malloc
分配16个对齐的缓冲区。但第二行和后续行与默认对齐方式4不对齐,除非行长度是4的倍数(这解释了为什么2x2和3x3不起作用,而4x4起作用)。1x1恰好工作,因为它没有第二行。

是否将
GL\u UNPACK\u对齐设置为
1