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

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

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

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

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

如果你打算使用std::string作为out参数,C ++ 03不保证存储的字符串在内存中是连续的,但是C ++ 11可以。 使用后者可以通过operator[]修改字符串,只要不修改终止NULL字符即可 。

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

这是一个OpenGL驱动程序错误,导致最大长度字符串被破坏的返回值。 请参阅https://forums.geforce.com/default/topic/531732/glgetactiveattrib-invalid/ 。 glGetActiveAttrib不会尝试写入具有0大小分配的new []调用返回的指针,但该字符串不会以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); } 

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

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

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

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

 cStyleAPI(&myArray[0], arraySize); 

如果你的cStyleAPI收到一个char *用于输入,那就是std::string::c_str()的用途。

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