我试图理解为什么在执行这段代码期间出现分段错误( SIGSEGV )。在测试while
指令中指定的条件时会发生此错误,但它不会在第一次迭代时发生,而是在第二次迭代时发生。
LPTSTR arrayStr[STR_COUNT];
LPTSTR inputStr;
LPTSTR str;
// calls a function from external library
// in order to set the inputStr string
set_input_str(param1, (char*)&inputStr, param3);
str = inputStr;
while( *str != '\0' )
{
if( debug )
printf("String[%d]: %s\n", i, (char*)str);
arrayStr[i] = str;
str = str + strlen((char*)str) + 1;
i++;
}
在阅读this answer之后,我在互联网上做了一些研究并找到this article,所以我尝试使用本文中读到的这段代码修改上面的代码(见下文)。但是,这种变化并没有解决问题。
for (LPTSTR pszz = pszzStart; *pszz; pszz += lstrlen(pszz) + 1) {
... do something with pszz ...
}
正如在this answer中假设的那样,代码似乎需要双空终止的字符串数组。因此,我想知道如何检查inputStr
字符串的内容,以检查它是否实际上只包含一个空终止符字符。
注意:从printf
指令打印的字符串中的字符数是第一次迭代时lstrlen(str)
函数调用返回的值的两倍。
答案 0 :(得分:2)
好了,既然你已经包含了剩下的代码,那么很明显它确实意味着解析一组连续的字符串。问题是你正在混合窄字符串和宽字符串类型。您需要做的就是更改变量定义(并删除强制转换):
char *arrayStr[STR_COUNT];
char *inputStr;
char *str;
// calls a function from external library
// in order to set the inputStr string
set_input_str(param1, &inputStr, param3);
str = inputStr;
while( *str != '\0' )
{
if( debug )
printf("String[%d]: %s\n", i, str);
arrayStr[i] = str;
str = str + strlen(str) + 1;
i++;
}
具体来说,问题出现在这一行:
while( *str != '\0' )
由于你没有将str
强制转换为char *
,因此比较正在寻找一个广泛而不是一个狭窄的区域。
答案 1 :(得分:1)
str = str + strlen(str) + 1;
你走出界限,改为
str = str + 1;
或简单地说:
str++;
答案 2 :(得分:1)
当然,你不一致地使用TSTR
和strlen
,后者假设TCHAR = char
在任何情况下,strlen
都会返回字符串的长度,这是它包含的字符数,不包括空字符。
你的算术是一个,但你知道在分配缓冲区时你必须在字符串的长度上添加一个。
然而,这里你从位置0开始并添加长度,这意味着你处于位置len
这是字符串的长度。现在,字符串从偏移0
到偏移len - 1
,偏移len
保持空字符。偏移量len + 1
超出范围。
有时你可能会因为阅读它而逃脱,如果有额外的填充,但它是未定义的行为,这里你有一个段错误。
答案 3 :(得分:1)
这对我来说就像是需要双空终止字符串数组的代码。我怀疑你传递一个空终止字符串。
所以你正在使用这样的东西:
const char* inputStr = "blah";
但代码需要两个null终止符。如:
const char* inputStr = "blah\0";
或者可能是包含多个字符串的输入值:
const char* inputStr = "foo\0bar\0";
请注意,这两个最终的两个字符串确实是双空终止的。虽然在字符串末尾只显式写入一个空终止符,但编译器会隐式添加另一个。
你的问题编辑引发了一个新的扳手?演员
strlen((char*)str)
非常可疑。如果你需要施放那么施法必定是错误的。人们想知道LPTSTR
为你扩展的内容。据推测,它扩展到wchar_t*
,因为您添加了强制转换以使代码编译。如果是这样,那么演员就没有好处。你对编译器撒谎(str
不是char*
)并且对编译器撒谎永远不会结束。
答案 4 :(得分:0)
Alter的答案已经给出了分段错误的原因。但是,我想补充一点,解析C风格字符串的常用方式更优雅,更简洁
while (char ch = *str++)
{
// other instructions
// ...
}
ch
的范围仅在循环体内。
旁白:将问题标记为C
或C++
,但不是两者都标记,它们是不同的语言。