如果我的代码是垃圾,我很抱歉,但我想在已经动态分配的字符串上尝试字符串操作,而不会丢失原始指针,这样当我继续并释放函数外部的内存时,我就不会释放错误的东西。
算法如下:
char* evenNumOfWords(char* str)
{
int spaceCounter = 0; // count the occurrences of space
int spaceIndices[strlen(str)]; // save the index of all space characters to avoid going through the whole array twice
char* endPointer = str + strlen(str);
int length;
for (int i = 0 ; i < strlen(str) ; i++)
{
if(str[i] == ' ')
{
spaceIndices[spaceCounter] = i;
spaceCounter++;
}
}
if (spaceCounter % 2 == 1) { // if there is an odd number of spaces there's an even number of words
for (int i = 0 ; i < spaceCounter ; i++)
{
length = (int)(endPointer - str);
memmove(str + spaceIndices[i] * sizeof(char) + 1, str + spaceIndices[i] * sizeof(char), length - spaceIndices[i] + 1); // move the string 1 byte forward starting from the place where there's a space
endPointer++;
str[spaceIndices[i]] = ' ';
}
}
return str;
}
也许我的逻辑完全不正确,但我的主要问题是,我真的可以在用 memmove 移走数据的内存上写入吗?因为我收到“代码 138(被信号 10 中断:SIGBUS)”,在谷歌搜索后我发现它是由在不可写内存上写入引起的。
提前致谢!
memmove
和memcpy
之间的唯一区别是memmove
非破坏性地复制字节。也就是说,如果源区域和目标区域重叠,memmove
可以正常工作,但 memcpy
可能不会。
您的问题可能是由于将常量字符串传递到函数中造成的。如果你这样做
foo = evenNumOfWords("the cat sat on the mat");
传入的字符串是文字,可能位于只读段中。
根据大家的建议我做了一些修改,非常感谢。
首先我改变了
spaceIndices[spaceCounter] = i;
到
spaceIndices[spaceCounter] = i + spaceCounter;
然后我继续使该函数无效,因为考虑到我是通过引用传递字符串并且它直接从堆中更改它,所以我不需要任何返回(也许我使用了错误的术语,请不要钉死我)
我继续使用 fgets 扫描控制台中的字符串,而不是传入代码中预先烘焙的字符串
回答我自己的问题,是的,你绝对可以在使用 memmove 移动的内存上写入。