内存访问冲突。这个看似简单的程序出了什么问题?

时间:2009-11-18 13:07:14

标签: c

这是一个快速的程序,我刚刚写了,看看我是否记得如何从头开始一个c ++程序。它只是反转一个字符串(就地),看起来一般对我来说是正确的。为什么这不起作用?

#include <iostream>
using namespace std;

void strReverse(char *original)
{
    char temp;
    int i;
    int j;
    for (i = 0, j = strlen(original) - 1; i < j; i++, j--)
    {
        temp = original[i];
        original[i] = original[j];
        original[j] = temp;
    }
}

void main()
{
    char *someString = "Hi there, I'm bad at this.";
    strReverse(someString);

}

7 个答案:

答案 0 :(得分:15)

如果你改变了这个,那么someString指向一个只读字符串文字的指针:

char *someString = "Hi there, I'm bad at this.";

,这使someString成为char的可修改数组,从字符串文字初始化

char someString[] = "Hi there, I'm bad at this.";

你应该有更好的结果。

虽然原始代码中的someString类型(char*)允许修改它指向的char,因为它实际上指向了字符串文字(这是不允许修改)尝试通过指针进行任何修改导致技术上称为未定义的行为,在您的情况下是内存访问冲突。

答案 1 :(得分:11)

如果这不是作业,C ++标签要求您使用C ++标准库来执行此操作:

std::string s("This is easier.");
std::reverse(s.begin(), s.end());

哦,它是int main(),总是int main(),该死的!

答案 2 :(得分:2)

您正在尝试修改字符串文字 - 在静态存储中分配的字符串。这是不端行为(通常会导致程序崩溃)。

您应该在反转之前分配内存并复制字符串文字,例如:

char *someString = "Hi there, I'm bad at this.";
char* stringCopy = new char[strlen( someString ) + 1];
strcpy( stringCopy, someString );
strReverse( stringCopy );
delete[] stringCopy;//deallocate the copy when no longer needed

答案 3 :(得分:2)

该行

char *someString = "Hi there, I'm bad at this.";

使someString指向一个字符串文字,不能修改。而不是使用原始指针,使用字符数组:

char someString[] = "Hi there, I'm bad at this.";

答案 4 :(得分:1)

您无法更改字符串文字(静态分配)。要做你想做的事,你需要使用类似的东西:

int main()
{
    char *str = new char[a_value];
    sprintf(str, "%s", <your string here>);
    strReverse(str);
    delete [] str;
    return 0;
}

[edit] strdup也有效,也是strncpy ...我确定还有其他各种方法:)

答案 5 :(得分:1)

请参见sharptooth的解释。

请改为尝试:

#include <cstring>

void main()
{
    char someString[27];
    std::strcpy( someString, "Hi there, I'm bad at this." );
    strReverse( someString );
}

更好的是,忘记char *并使用<string>代替。毕竟这是C ++,而不是C.

答案 6 :(得分:0)

使用更严格的编译器设置时,此代码甚至不应编译:

char* str = "Constant string";

因为它应该是常数:

const char* str = "Now correct";
const char str[] = "Also correct";

这使您可以更快地捕获这些错误。或者你可以使用一个字符数组:

char str[] = "You can write to me, but don't try to write something longer!";

为了完全安全,只需使用std :: string。毕竟你正在使用C ++,原始字符串操作非常容易出错。