尝试将新值分配给指向字符的指针数组时 C++ 崩溃

C++ crashing when attempting to assign a new value to a pointer array pointing to chars

所以我希望通过简单地将 32 添加到 char 的值来将大写字符转换为小写,这实际上给出了它的小写等价物。

在主体中我声明了指针数组并分配了 3 个单词:

int main()
{
    char *dictionary[10];
    dictionary[0] = "aUto";
    dictionary[1] = "caR";
    dictionary[2] = "Door";
    int arrayCount = 3;
    upperCase(dictionary, &arrayCount);
}

在我尝试转换的函数中:

void upperCase(char *dictionary[], int *arrayCount)
{
    cout << "In upperCase\n";
    for (int i = 0; i < 3; i++)
        for (int k = 0; dictionary[i][k] != '[=11=]'; k++)
        {
            if (dictionary[i][k] < 97 && dictionary[i][k] > 64) // If     capital is less than the value of 'a' (97)
            {
                dictionary[i][k] += 32;
            }
            else
                cout << "Not a capital\n";
        }
}

程序在字典[i][k] += 32处崩溃; 我试图替换字符串中的字符(由数组元素指向)。即使先转换字母也行不通。 例如:字典[i][k] = 'a'; 仍然使我的程序崩溃。 运行 windows

上的 Eclipse C++

大部分内容现在可能已包含在评论中。刚看了。是的。我还没来得及忙就忙起来了 post。无论如何,这里是问题的分解:

char *dictionary[10];

这很酷。

dictionary[0] = "aUto";

这不酷。 "aUto" 是一个 string literal。一串常量值。如何存储取决于编译器。你可以读它,但你不应该指望能够写它。 Treat 就好像被定义为 const char *,因为就语言而言,它是 const char *

为什么这不酷是因为 OP 将 const char * 分配给了 char *。将指向常量的指针分配给指向非常量的指针应该至少会产生警告。最好在编译器中调高警告级别以尽早发现此类错误。在 g++ 和类似语言中,我喜欢 -Wall-Wextra-pedantic 的副顺序。在 MSVC 中,导航 Properties->C/C++->General 并使用 Warning Level。 EnableAllWarnings 看起来是个不错的起点。

现在常量值由非常量指针引用,编译器不知道下一位可能是致命的。

dictionary[i][k] += 32;

尝试将32加到一个字符上,这部分没问题,然后将结果存储到一个不可写的位置。这是不允许的,但尝试不可能的事情的确切处理取决于编译器。你有一个程序崩溃,这对编译器来说非常好。该程序本可以保留 运行,破坏一些其他内存 space,然后死掉,让您不知道实际发生了什么以及要调试什么。

如何使这些字符串不是常量:

  1. 使用 std::string rather than char *. In C++ this is by far the better option. And while you're at it, use std::vector 代替数组。
  2. 但这闻起来像作业,你可能不被允许使用 std::string。在这种情况下,分配存储并将字符串文字复制到存储中,以便它们有真正的、可修改的内存支持它们。

编码风格注意事项:

不要使用像 97 这样的数值,而是使用字符 'a'。它的工作原理相同,您的意图更容易确定。最好省去所有麻烦并使用 std::tolower

还有一个巧妙的技巧,您可以使用 std::transform、std::string 和 std::tolower 来删除大部分 upperCase 函数。稍微试验一下,您就会发现它。 更正(我似乎总是在这个问题上发现自己):使用 tolower,而不是 std::tolower,因为 std::tolower 的语言环境过载使得你想要哪个 std::tolower 变得模棱两可。

这个:

for (int i = 0; i < 3; i++)

有点傻。你传入了 arrayCount。如果您更改数组中的项目数,您不妨使用它并避免混淆

for (int i = 0; i < *arrayCount; i++)

如果您被允许使用 C++,那么您可以改为:

  1. 使用STL
  2. 使用向量,对于这些类型的事情通常更容易处理
  3. 使用 Stringstream(或一般的流)

虽然这只是一个想法。但是您的代码肯定看起来更像是 C 问题(宁愿使用 malloc 分配动态内存)而不是 C++ 问题。

此外,您确定 dictionary[i][k] += 32 操作真的按照您认为的方式进行吗?通常在这些类型的代码中崩溃意味着您的指针指向 unallocated/invalid 位置。