以下是我的示例代码。它只是一个样本,类似于我在我的应用程序中使用的代码。
#define STR_SIZE 32
void someThirdPartyFunc(const char* someStr);
void getString(int Num, const char* myStr)
{
char tempStr[] = "MyTempString=";
int size = strlen(tempStr) + 2;
snprintf((char*)myStr, size, "%s%d", tempStr, Num);
}
int main()
{
const char * myStr = new char(STR_SIZE);
getString(1, myStr); // get the formated string by sending the number
someThirdPartyFunc(myStr); // send the string to the thirdpartyFunction
delete myStr;
return 0;
}
如果我使用此代码,我会收到异常。我认为问题在于删除“myStr”。但删除是非常必要的。
还有其他方法可以在getString中格式化字符串并将其发送到ThirdPartyFunc吗?
提前致谢。
答案 0 :(得分:9)
你分配的不是一个字符数组,而是分配一行字符:
const char * myStr = new char(STR_SIZE);
并且使用值STR_SIZE
初始化一个已分配的char,在这种情况下导致“char溢出”。
如果你想要一个大小为STR_SIZE
的数组:
const char * myStr = new char[STR_SIZE];
(注意矩形[])。你必须使用delete[]
运算符解除分配这种分配的内存块。
个人注意事项:您上面编写的代码(手动分配字符串等)具有良好的教育意义;你会做很多这样的错误,从而了解C / C ++的内部工作原理。对于您不希望的生产代码,对于生产代码,您希望std::string
或其他字符串容器避免重复与字符串相关的错误。一般来说,你不是那个成功重塑字符串库如何工作的人。其他容器类型也是如此,例如动态可扩展数组(std::vector
)或字典类型或其他类型。但是,对于上面的代码进行教育摆弄是一个很好的目的。
您的代码段中还有其他问题(将const char*
移交给函数,然后修改ram,而不是在调用size
时正确计算snprintf
参数等),但这些与你的段错问题无关。
答案 1 :(得分:5)
重新技术,而不是
const char * myStr = new char(STR_SIZE);
DO
char const myStr[STR_SIZE] = "";
请注意,两者都存在无法修改字符串的问题。
但您只询问了分配/解除分配问题。
但是,在语言技术水平以上的水平上存在很多错误。
这是原始代码,完整:
void someThirdPartyFunc(const char* someStr);
void getString(int Num, const char* myStr)
{
char tempStr[] = "MyTempString=";
int size = strlen(tempStr) + 2;
snprintf((char*)myStr, size, "%s%d", tempStr, Num);
}
int main()
{
const char * myStr = new char(STR_SIZE);
getString(1, myStr); // get the formated string by sending the number
someThirdPartyFunc(myStr); // send the string to the thirdpartyFunction
delete myStr;
return 0;
}
以下是如何在C ++级别执行此操作:
#include <string> // std::string
#include <sstream> // std::ostringstream
using namespace std;
void someThirdPartyFunc( char const* ) {}
string getString( int const num )
{
ostringstream stream;
stream << "MyTempString=" << num;
return stream.str();
}
int main()
{
someThirdPartyFunc( getString( 1 ).c_str() );
}
#define
从更自然的代码中消失了,但请注意,即使使用全部大写宏名称,它也很容易导致不需要的文本替换。无论如何,大喊大叫是一个眼睛(这就是为什么它是宏名称约定,而不是其他一些约定)。在C ++中,只需使用const
代替。