C/C++ 有效指针但获得 EXC_BAD_ACCESS 和 KERN_INVALID_ADDRESS

Posted

技术标签:

【中文标题】C/C++ 有效指针但获得 EXC_BAD_ACCESS 和 KERN_INVALID_ADDRESS【英文标题】:C/C++ Valid pointer but getting EXC_BAD_ACCESS and KERN_INVALID_ADDRESS 【发布时间】:2014-11-30 03:34:52 【问题描述】:

我已经为此绞尽脑汁好几个小时了,但我找不到任何东西。

潜在相关信息:

在 OSX 10.10.1 Yosemite 上运行

同样的代码在 Windows 上运行良好。

每次我运行它时,它都会在完全相同的位置中断。

应用程序是一个使用glfw3创建窗口的OpenGL应用程序。

没有线程,它只是一个单线程应用程序,因此指针不会被覆盖或释放。

这两个方法包含在两个单独的 .c 文件中,它们被编译为 c++ 并包含在我链接到的构建库中。库中的其他方法也可以正常工作。

OPchar* OPstreamReadLine(OPstream* stream) 
    OPchar buffer[500];
    i32 len, i;

    // ALL WORKS FINE
      // check to see if we are at the end of the stream or not
      if(stream->_pointer >= stream->Length) return 0;

      // Prints out the contents of the stream, and the start of the pointer just fine
      OPlog("Buffer %s | Pointer %d", stream->Data, stream->_pointer);
      sscanf((OPchar*)stream->Data  stream->_pointer, "%500[^\n]", buffer);
      len = strlen(buffer);
      stream->_pointer = len  1;

      // Spits out 'Read Hello of len 5'
      OPlog("Read %s of len %d", buffer, len);



    // ISSUE STARTS HERE
    // OPchar is a typedef of char
    // STEP 1. Make the call
    OPchar* result = OPstringCreateCopy(buffer);

    // STEP 6. The Pointer is printed out correctly, its the same thing
    // ex: Pos: 0xd374b4
    OPlog("Pos: 0x%x", result);

    // STEP 7. This is where it breaks
    // EXC_BAD_ACCESS and KERN_INVALID_ADDRESS
    // What happened? 
    // Did returning the pointer from the function break it?
    OPlog("len: %d", strlen(result));

    OPlog("Result %s", result);

    return result;



OPchar* OPstringCreateCopy(const OPchar* str) 
    i32 len = strlen(str);

    // STEP 2. Prints out 'Hello 5'
    OPlog("%s %d", str, len);

    // Allocates it (just uses malloc)
    OPchar* result = (OPchar*)OPalloc(sizeof(OPchar) * (len + 1));

    // Copies the previous string into the newly created one
    strcpy(result, str);

    // Ensures that it's null terminated
    // even though strcpy is supposed to do it
    result[len] = NULL;

    // STEP 3. Gives a good pointer value
    // ex: Pos: 0xd374b4
    OPlog("Pos: 0x%x", result);

    // STEP 4. Prints out '5'
    OPlog("len: %d", strlen(result));

    // STEP 5. Prints out 'Hello'
    OPlog("hmmm: %s", result);

    // Just return this same pointer
    return result;
 

我已经用不使用解决问题的 sscanf 东西的版本替换了这些函数,但是我现在遇到了同样的问题,另一个返回的指针变得无效。这个例子更容易解释,所以我想我会从那里开始。

【问题讨论】:

如果您必须使用 C 风格的格式化函数,请使用正确的转换说明符。 %d 不适合 size_t,%x 不适合指针。 最后,如果您使用 -Wall 后仍未收到有关此代码的任何警告,请考虑针对任何提供 OPlog 的软件提交错误报告,确保您收到警告是他们的责任。 【参考方案1】:

这是一个理论,你可以去测试一下。不要使用%x 来打印您的指针,而是使用%p。您可能使用的是 64 位操作系统而没有意识到这一点。问题可能是您没有为OPstringCreateCopy 提供原型,在这种情况下,返回值被视为int(32 位)而不是指针(64 位)。由于您只打印出result 的 32 位,看起来指针是有效的,但高 32 位可能已经丢失。

解决此问题的方法是确保始终为所有函数提供原型。应该有一些编译器警告可以打开,以帮助您找到非原型函数的用途。您可能还想检查您的代码并检查任何其他 64 位问题,例如您是否曾经将指针转换为 int。

【讨论】:

以上是关于C/C++ 有效指针但获得 EXC_BAD_ACCESS 和 KERN_INVALID_ADDRESS的主要内容,如果未能解决你的问题,请参考以下文章

手把手教你深入理解c/c++中的指针

C/C++学习笔记:智能指针详解

C/C++学习笔记:智能指针详解

节点 ffi napi,调用返回 true 但指针中没有结果

如何使用 Mono Project 将 C/C++ 指针传递和保存到 C#,并将它们返回

linux C/C++中deferencedereferenced含义(解引用)