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

时间:2014-11-30 03:34:53

标签: c++ c macos opengl

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

潜在相关信息:

  • 在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内容的版本,但是我现在遇到了同样的问题,而另一个返回的指针变得无效。这个例子更容易解释,所以我想我会从那里开始。

1 个答案:

答案 0 :(得分:3)

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

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