将std :: string传递给C风格API是否安全?

时间:2013-05-07 17:44:51

标签: c++ c string

很好地定义了C ++将std :: vector传递给期望输出数组的C API,因为std :: vector是连续的:

std::vector<char> myArray(arraySize);
cStyleAPI(&myArray[0], arraySize);

以相同的方式将std :: string传递给C API是否安全?在标准C ++ 03中是否有任何保证std :: string是连续的并且在这种情况下与std :: vector的工作方式相同?

5 个答案:

答案 0 :(得分:10)

如果C API函数要求对std::string的内容进行只读访问,则使用std::string::c_str()成员函数传递字符串。这保证是一个以空字符结尾的字符串。

如果您打算使用std::string作为 out 参数,C ++ 03不保证存储的字符串在内存中是连续的,但C ++ 11可以。使用后者,只要您don't modify the terminating NULL character,就可以通过operator[]修改字符串。

答案 1 :(得分:5)

所以,我知道这已经得到了解答,但我在Praetorian的回答中看到了你的评论:

  

这是一个OpenGL驱动程序错误,导致返回值   最大长度字符串被破坏。看到   https://forums.geforce.com/default/topic/531732/glgetactiveattrib-invalid/。   glGetActiveAttrib不会尝试写入由返回的指针   new []调用0大小分配,但字符串不为null   终止。然后,在代码的后面,非空终止字符串是   复制到std :: string进行存储,从而产生读缓冲区   溢出。我也很困惑,只是在这里查看是否   std :: string会让事情变得更容易理解。

嗯...原谅我,但如果这个是你的问题,那么所有这些解决方案似乎都过于复杂了。如果问题归结为你得到一个0作为你需要的缓冲区大小这一事实(这意味着你将得到一个非NULL终止的字符串,因为没有空间用于NULL终止符)然后只需确保NULL终止符始终存在:

int arraySize; 

/* assume arraySize is set to the length we need */
...

/* overallocate by 1 to add an explicit NULL terminator. Just in case. */
char *ptr = malloc(arraySize + 1);

if(ptr != NULL)
{
    /* zero out the chunk of memory we got */
    memset(ptr, 0, arraySize + 1);

    /* call OpenGL function */
    cStyleAPI(ptr, arraySize);

    /* behold, even if arraySize is 0 because of OpenGL, ptr is still NULL-terminated */
    assert(ptr[arraySize] == 0);

    /* use it */
    ...

    /* lose it */
    free(ptr);
}

对我来说,这似乎是最简单,最安全的解决方案。

答案 2 :(得分:1)

是的,但您需要使用c_str方法传递它们以保证空终止。

答案 3 :(得分:0)

不,它不是,但通常是因为C字符串被假定为零终止,而指针指向char则不是。 (如果您使用string,则可以使用string::c_str()代替,即0终止。)

无论如何,C ++ 11确实要求vector的元素在内存中是连续的。

答案 4 :(得分:0)

cStyleAPI(&myArray[0], arraySize);

如果cStyleAPI收到char *作为输入,那就是std::string::c_str()的用途。

如果收到预先分配的char *用于输出,则。在这种情况下,您应该使用std::vector<char>std::array<char>