printf 导致 EXC_BAD_ACCESS(code=EXC_I386_GPFLT) 警告并在运行时冻结

Posted

技术标签:

【中文标题】printf 导致 EXC_BAD_ACCESS(code=EXC_I386_GPFLT) 警告并在运行时冻结【英文标题】:printf causes EXC_BAD_ACCESS(code=EXC_I386_GPFLT) warning and freezes at runtime 【发布时间】:2014-08-10 14:57:18 【问题描述】:

我有一个由 3 个嵌套的 for 循环和一个 if 语句组成的函数,里面有:

int buffsize = valuex*3;
    //int buffsize = (LEDS+1)*3;
    char buffer[buffsize];
    init_buf(buffer, buffsize);
    // while(counter <= linecount)

    int x = 0;
    int y = 0;
    char *bufpointer=buffer;

    for (x=0; x<=valuex; x++) 

        for (y=0;y<=LEDS; y++) 

            for (int i=0; i<=linecount; i++) 

                if (pixels[i].y==y) 

                    snprintf(bufpointer+=strlen(bufpointer), buffsize, "%s%d%d%d",buffer, pixels[i].r,pixels[i].g, pixels[i].b );
                    printf("buffer contents: %s\n",buffer);


                

            
         printf("buffer contents: %s\n",buffer);  //placed for debugging
        

    



    /**************** buffer initialiser ********************/

    void init_buf(char *buf, size_t size)
    int i;
    for(i=0; i<size; i++)
        buf[i] = '0'; // int to char conversion
     
    

bufpointer 是指向 char 数组缓冲区的指针。

我正在尝试从像素[] 结构中读取整数值并将它们全部添加到单个缓冲区中。

我的问题是我在 printf 函数中收到一条警告:线程 1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)

在运行期间,程序一直运行到 printf 语句并在那里冻结

【问题讨论】:

您需要添加更多代码(在调用 snprintf 之前),以便我们可以看到您如何分配缓冲区以及有关缓冲区指针类型及其方式的详细信息正在使用。这两行断章取义是不够的,但我的猜测是,您要么正在访问尚未分配的内存,要么正在某处超出缓冲区的末尾。 我同意肯。例如,我很想知道指向的缓冲区是如何初始化的,以及是否确保那里总是有一个以空字符结尾的字符串。另外,当bufpointer增加时,你是否确保buffsize减少到剩余空间? 我现在添加了更多代码,我不确定如何在每次迭代后减少 buffsize 的值,我还尝试使用 sprint 运行该函数,因为它不需要 buffsize 作为参数,但失败了完全相同的问题 【参考方案1】:

听起来您正在访问超出数组末尾的内存。

bufpointer+=strlen(bufpointer)buffsize 的组合看起来很可疑。我假设您使用bufpointer 将多个字符串连接到一个缓冲区中,方法是使每个snprintf 调用开始写入前一个调用留下的空字节。如果是这种情况,snprintf 的第二个参数应该是缓冲区中剩余 的空间量,而不是缓冲区的 大小。例如,如果您有一个可容纳 100 个字符的缓冲区,并且第一个 snprintf 调用写入了 10 个字符,那么对于第二个调用,大小限制应该是 90,而不是 100。

您没有发布足够的代码来显示 bufpointerbuffsize 的初始化方式以及它们是否被循环更改,因此尚不清楚这是否是您的问题的原因,但我怀疑是的。

【讨论】:

bufpointer 和 buffsize 是在任何循环开始之前初始化的常量,所以从你刚才所说的我的代码是错误的,因为 buffsize 不会根据剩余空间进行调整,我该怎么做? 使用临时 size_t sz=strlen(bufpointer);就在 snprintf() 之前,您可以在其中使用 bufpointer+=sz 和 buffsize-=sz 当您将前面字符串的长度添加到bufpointer 时,您还需要从buffsize 中减去相同的数字。 (请注意,snprintf 返回它写入的字符数;您可以使用它而不是调用 strlen。)

以上是关于printf 导致 EXC_BAD_ACCESS(code=EXC_I386_GPFLT) 警告并在运行时冻结的主要内容,如果未能解决你的问题,请参考以下文章

访问 NSManagedObject 会导致 EXC_BAD_ACCESS

为啥在构造函数中释放会导致 EXC_BAD_ACCESS?

导致 EXC_BAD_ACCESS

awakeAfterUsingCoder() 导致 EXC_BAD_ACCESS

委托分配导致 EXC_BAD_ACCESS

导致 EXC_BAD_ACCESS 的指针分配