0

要遵循的代码片段。

我有一个结构(示例代码有类,都试过了,效果相同),它将存储许多 char *. 我为类创建了一个构造函数,将它们中的大多数初始化为 = ""; 在尝试修改类实例的该成员时,strncpy 等都报告访问被拒绝。当我在内部结构/类成员函数的范围内使用这些函数时,它们甚至会报告拒绝访问。

我的假设是拥有一个结构/类的 char * 成员没什么大不了的,也没什么特别的(除了作为指向 char 的指针,这要求它在使用之前的某个时间点进行初始化,并在某些时候销毁)。

如果有人能告诉我我的假设在哪里错了,我将不胜感激,并指导我查阅一些可以澄清发生了什么的文献。我目前正在编译vs2008完整版下的代码。

我希望运行此代码的人会收到关于被拒绝访问某个内存位置的运行时错误。

我也希望当我制作一个 char * mystr 时,我稍后会说 mystr = ""; 初始化内存以供 mystr 然后使用。

我还想认为我不是白痴,但是当我尝试使用本地窗口来确定某个变量的精确内存地址时,我似乎无法让 ide 告诉我内存在哪里是在。我必须在内存窗口中走运。那好吧。

帮助!提前致谢。我讨厌处理这些愚蠢的 char * 因为我总是以某种方式把它们搞砸,而且我对它们如何工作的假设是有缺陷的。我想改变这一点,以便我像他们的工具一样指挥他们,而不是他们让我感到沮丧。

再次感谢您的考虑。乔什

#include <stdio.h>
#include <string.h>



   class mystruct {
    public:
 int A;
 char* B;
 char* C;

 mystruct() {
  A = 0xFE;
  B = new char[32];
  B = "";
  C = "test";
 }

 void test(char *input) {
  strncpy(B,input, strlen(input));
 }
    };

    int main(char* argv[], int argc) {

 mystruct work;
 char wtf[32];

    // work.A = 0xbb;
 work.test("gotchabitch!");
    // sprintf(wtf, "address of work is %x" , &work);
    // strncpy(work.C,"gotchabitch!\0",strlen("gotchabitch!\0"));
  strncpy(work.B,"gotchabitch!",strlen("gotchabitch!"));
 printf("%d;%s;%s;", work.A, work.B, work.C); 

 return 0;
    } 

对所有人的回应:好的,我了解到,当您将字符串文字分配给 char * 时,您实际上是在说 char * const B = "something"。(这与 const char * B = something 有什么不同,后者是一个地址不能改变的指针,而前者是指向不能改变的内存的指针?)。无论哪种方式,这都解释了我收到的错误消息。谢谢大家。

4

3 回答 3

1
B = new char[32];
B = "";

您首先分配由newto返回的指针B,然后将指向字符串文字的指针分配给""to B,有效地覆盖由返回的指针new

正如 Jonathan Leffler 解释的那样,字符串文字是只读的,因此当您尝试写入 指向的字符串文字 ( "")时会遇到错误B

如果要将空字符串存储在 中B,则需要使用类似的库函数strcpy()(或者最好使用更安全的函数,例如snprintf())。在这种情况下,您也可以只分配\0B[0],因为这是同一件事。在 C 和 C++ 中,您不能使用=.

理想情况下,您应该只使用std::string而不是原始 C 字符串;那么你就不必担心这种事情了。

于 2010-07-11T00:42:31.990 回答
1

问题是当您尝试这样做时:

strncpy(work.C, "something", strlen(something));

您正在复制只读数据 - 这不是一个好主意。那是因为指针 C 指向一个字符串字面量。不允许覆盖字符串文字。类似的评论适用于 B - 但你也有内存泄漏。

关键是您对“运行时”而不是“编译时”错误的评论。不是会员不可访问;当您按原样初始化它时,它就是不可滥用的。

于 2010-07-11T00:44:45.713 回答
1

错误在该行中:

C = "test";

在 mystruct 的构造函数中。 "test"是指向只读内存的指针,使用它来初始化非常量指针是不安全的。编译器不强制执行此操作的唯一原因是在人们关心 const 正确性之前创建了大量 C 代码,应该声明const但没有声明。

B = "";

同样不是类型安全的。

于 2010-07-11T01:18:47.893 回答