是否可以在C中使用memmove移走的内存上进行写入?

问题描述 投票:0回答:2

如果我的代码是垃圾,我很抱歉,但我想在已经动态分配的字符串上尝试字符串操作,而不会丢失原始指针,这样当我继续并释放函数外部的内存时,我就不会释放错误的东西。

算法如下:

  • 接收动态分配的包含多个单词的字符串
  • 如果单词数为偶数,则将每个单词之间的空格数设置为 2。 否则保留 1 个空格。
    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)”,在谷歌搜索后我发现它是由在不可写内存上写入引起的。

提前致谢!

c memory malloc dynamic-memory-allocation memmove
2个回答
1
投票

memmove
memcpy
之间的唯一区别是
memmove
非破坏性地复制字节。也就是说,如果源区域和目标区域重叠,
memmove
可以正常工作,但
memcpy
可能不会。

您的问题可能是由于将常量字符串传递到函数中造成的。如果你这样做

foo = evenNumOfWords("the cat sat on the mat");

传入的字符串是文字,可能位于只读段中。


0
投票

根据大家的建议我做了一些修改,非常感谢。

首先我改变了

spaceIndices[spaceCounter] = i;

spaceIndices[spaceCounter] = i + spaceCounter;

然后我继续使该函数无效,因为考虑到我是通过引用传递字符串并且它直接从堆中更改它,所以我不需要任何返回(也许我使用了错误的术语,请不要钉死我)

我继续使用 fgets 扫描控制台中的字符串,而不是传入代码中预先烘焙的字符串

回答我自己的问题,是的,你绝对可以在使用 memmove 移动的内存上写入。

© www.soinside.com 2019 - 2024. All rights reserved.