2010-07-11 123 views
0

代码片段如下。public char *类/结构不可访问的成员?!?!?!po

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

它是我的假设,有一个结构/类的char *成员是没有什么大不了的,没有什么特别的(除了是一个字符的指针,它需要在被使用之前的某个点初始化,并且在某些时候被摧毁)。

我很感激,如果有人能告诉我我的假设在哪里出错了,并且指引我去了解一些正在发生什么的文献。我目前正在编译vs2008完整版的代码。

我期望有人会运行这段代码会得到一个关于被拒绝访问某个内存位置的运行时错误。

我也希望当我做一个char * mystr,当我后来说mystr =“”;内存初始化为mystr然后被使用。我也想认为我不是一个白痴,但当我尝试使用本地窗口来确定某个变量的内存地址的确切位置时,我似乎无法得到ide告诉我记忆在哪里。我希望在记忆窗口中幸运。好吧。

帮助!提前致谢。我讨厌处理这些愚蠢的char * cuz,我总是把它们搞乱了,而我关于它们如何工作的假设也被忽略了。我想改变这一点,以便我命令他们像他们的工具,而不是让他们感到挫败。

再次感谢您的考虑。 乔希

#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 =“东西”。 (和const char * B没有什么不同,后者是一个地址不能改变的指针,而前者是指向内存的指针,不能改变)。无论哪种方式,这解释了我得到的错误消息。谢谢大家。

+0

您的最终分析几乎完全正确......但您有两种类型的落后。 'const char *'是指向内存的指针,不能被改变(像字符串文字),而'char * const'是指针,不能被重新指派指向其他内存,尽管你可以改变它指向的内存至。 – 2010-07-11 16:45:52

回答

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

您先new返回的指针分配给B,那么你的指针字符串赋予字""B,有效覆盖由new返回的指针。

As Jonathan Leffler explains,字符串文字是只读的,所以当您尝试写入字符串字面量("")遇到一个错误指出,由B

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

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

1

的问题是,当你试图做的事:

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

要复制在只读数据 - 这是不是一个好主意。这是因为指针C指向一个字符串文字;不允许覆盖字符串文字。类似的评论适用于B - 但你也在泄漏记忆。

关键在于您对“运行时间”而不是“编译时间”错误的评论。这不是该成员无法访问;如果你已经初始化它,那就是不可滥用的。

1

的错误是在该行:

C = "test"; 

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

B = ""; 

同样不是类型安全的。