【问题标题】:c++ - char const * const * - <error reading characters of string>c++ - char const * const * - <错误读取字符串字符>
【发布时间】:2018-07-12 00:54:23
【问题描述】:

我有一个变量,它是一个指向一个常量指针的指针,该指针指向一个常量字符。

char const * const * words;

然后我将单词“dog”添加到该变量中。

words = (char const * const *)"dog";

但是,当我调试代码时,它会说明以下内容:

{0x616d7251 Error reading characters of string.}

我的问题是,我将如何正确访问该变量的字符以记录字符串的每个单独字符。

下面是一些示例代码:

char const * const *words;
words = (char const * const *)"dog";

for (int i = 0; i < 5; ++i)
{
    char c = (char)words[i]; // Gives me, -52'i symbol', 'd', and then '\0'
    // How do I access the 'o' and 'g'?
}

提前感谢您的帮助。

【问题讨论】:

  • 你到底想做什么?
  • std::vector&lt;std::string&gt;&gt; words = { "dog" };
  • @pm100 他的编程同事有没有把他吊死?
  • 所以words 指向 1000 个大型 malloc 缓冲区。然后将words 分配给点“狗”,并使用错误的演员来实现它。这段代码很破。
  • @manni66 我很遗憾需要使用 char const * const * words 变量。

标签: c++ pointers char constants


【解决方案1】:

也许你是这个意思

char const * const words = "dog";

for (int i = 0; i < strlen(words); ++i)
{
    char c = words[i]; 
}

现在当然在 c++ 代码中你应该真正使用 std::string

【讨论】:

  • @pm100 仍然不太有效。更清楚地说,调试器指出“words”在读取字符串字符时出错。然后这样做时,它会给我这样的字符:-52 'i symbol'、'd'、'\0'。我从来没有使用过这样的变量,所以我所做的很多事情只是为了了解它是如何工作的。
  • 你是对的,我发誓我已经测试过了,但现在无法编译。固定
  • 但 OP 在评论中说“不幸的是,我需要使用 char const * const * words 变量。”
【解决方案2】:

简答:

您的程序有未定义的行为。要删除未定义的行为,请使用:

char const * word = "dog";
for (int i = 0; i < std::strlen(word); ++i)
{
    char c = word[i];
}

char const * word = dog;
char const * const *words = &word;
for (int i = 0; i < std::strlen(*words); ++i)
{
    char c = (*words)[i];
}

长答案:

您正在强制从char const* 转换为char const* const* 并将持有chars 的内存位置视为持有char const*s。不仅如此,您还使用越界索引访问内存。

假设字符串"dog" 保存在某个内存位置(它需要四个字节,包括空字符)并给它一个地址。

a1
|
v
+---+---+---+----+
| d | o | g | \0 |
+---+---+---+----+

您可以将地址a1 视为char const* 类型的指针的值。这根本不是问题。但是,通过使用:

words = (char const * const *)"dog";

您将a1 视为拥有char const* 类型的对象。

让我们暂时假设您的机器使用 4 个字节作为指针并使用小端序作为指针。

words[0] 计算为指针。它的值是:

 'd' in decimal +
 256 * 'o' in decimal +
 256*256 * 'g' in decimal +
 256*256*256 * '\0' in decimal.

之后,您将该值截断为char,这将返回字符d,这还不错。当您访问words[1] 时,有趣的部分(未定义的行为)就开始了。

words[1]*(words+1) 相同。 words+1 计算为一个指针,其值为地址a2

                 a2
                 |
                 v
+---+---+---+----+
| d | o | g | \0 |
+---+---+---+----+

如您所见,它指向的内存超出了编译器为您分配的内存。取消引用该指针会导致未定义的行为。

【讨论】:

  • 感谢您的描述性解释。它有助于让事情变得清晰。综上所述,这是否意味着单词在技术上只能包含一个单词地址?或者它可以容纳多个?
  • @aromans,它当然可以指向多个单词。例如char const* word1 = "dog"; char const* word2 = "kittens"; char const* words[2] = {word1, word2};.
  • @S Rahu,是否有可能将单词作为值/参数传递,例如传递所有单词而不是单个单词的 char const * const *?
  • @aromans,你可以。但是您还必须传递另一个值来指示该数组中有多少元素,或者传递一个标记指针值NULL
  • 对于 size_t 值,我使用 strlen。这听起来不对。如果您还有其他问题,最好使用合适的minimal reproducible example 发布另一个问题。
【解决方案3】:

你总是错过第二个*

忽略const 的东西,你声明了一个char** word,它是一个指向单个字符指针的指针。你不会得到一个字或很多字,而投射只是隐藏了问题。

要通过这样的指针访问"dog",您需要采取额外的步骤;创建一个包含"dog" 的变量,并将其地址放入您的word

【讨论】:

  • 非常感谢!我什至没有意识到,它只是点击!我现在可以正常工作了,再次感谢您!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多