简体   繁体   English

public char *无法访问类/结构的成员?!?!?!po

[英]public char * member of a class/struct inaccessible?!?!?!po

Code snippet to follow. 遵循的代码段。

I have a struct (example code has class, tried both, same effect) that will store a number of char *. 我有一个结构(示例代码具有类,都尝试过,具有相同的效果),该结构将存储许多char *。 I made a constructor for the class that initializes most of them to = ""; 我为该类创建了一个构造函数,将它们中的大多数初始化为=“”; Upon attempting to modify that member of an instance of the class, strncpy et all report access denied. 尝试修改该类实例的成员时,strncpy等会报告所有访问被拒绝。 These functions even report access denied when i use them in the scope of internal struct/class member functions. 当我在内部结构/类成员函数的范围内使用它们时,这些函数甚至报告访问被拒绝。

Its been my assumption that having a char * member of a struct/class was no big deal and nothing special (apart from being a pointer to a char, which required that it be initialized at some point before being used, and destroyed at certain times). 我一直认为拥有struct / class的char *成员没有什么大不了,也没有什么特别的(除了是指向char的指针外,这要求在使用之前先对其进行初始化,然后在某些时候销毁) )。

I appreciate it if someone could tell me where my assumptions have been wrong, and direct me to some literature that would clarify whats going on. 如果有人可以告诉我我的假设在哪里有错,并将我引向一些可以阐明正在发生的事情的文献,我将不胜感激。 I am currently compiling the code under vs2008 full edition. 我目前正在编译vs2008完整版下的代码。

I expect that someone who will run this code will get a runtime error about being denied access to a certain memory location. 我希望将要运行此代码的人会收到有关拒绝访问某个内存位置的运行时错误。

I also expect that when I make a char * mystr that when I later say mystr = ""; 我还希望当我创建一个char * mystr时,稍后再说mystr =“”; that the memory is initialized for mystr to then be used. 初始化为mystr使用的内存。

I'd also like to think i'm not an idiot, but when I try to use the locals window to determine the precise in memory address of a certain variable, I can't seem to get the ide to tell me where the memory is at. 我也想以为我不是白痴,但是当我尝试使用locals窗口来确定某个变量的精确内存地址时,我似乎无法告诉我内存在哪里在。 I ahve to get lucky in the memory window. 我要在内存窗口中幸运。 oh well. 那好吧。

help! 救命! Thanks in advance. 提前致谢。 I hate dealing with these stupid char * cuz I always mess them up somehow, and my assumptions about how they work are flawwed. 我讨厌处理这些愚蠢的char * cuz,我总是以某种方式弄乱它们,而我对它们如何工作的假设也有缺陷。 I want to change this so that I command them like the tools they are, not them frustrate me. 我要更改此设置,以便我像使用工具一样命令他们,而不是让他们感到沮丧。

Thanks again for your consideration. 再次感谢您的考虑。 Josh 乔希

#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;
    } 

Response to all: Ok, I've learned that when you assign a string literal to a char * that you're really saying char * const B = "something". 对所有人的答复:好的,我了解到,当您将字符串文字分配给char *时,您实际上是在说char * const B =“ something”。 (isn't that different from const char * B = something, where the latter is aa pointer whose address can not change, as opposed to the former which is a pointer to memory that can't be changed?). (与const char * B =某物有什么不同,后者是地址不能更改的指针,而前者是指向不能更改的内存的指针?)。 Either way, this explains the error message that I got. 无论哪种方式,这都可以解释我收到的错误消息。 Thank you all for that. 谢谢大家。

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

You first assign the pointer returned by new to B , then you assign a pointer to the string literal "" to B , effectively overwriting the pointer returned by new . 首先,将new返回的指针分配给B ,然后将指向字符串文字""的指针分配给B ,从而有效地覆盖new返回的指针。

As Jonathan Leffler explains , string literals are read-only, so you encounter an error when you try to write to the string literal ( "" ) pointed-to by B . 正如Jonathan Leffler解释的那样 ,字符串文字是只读的,因此当您尝试写入B指向的字符串文字( "" )时会遇到错误。

If you want to store the empty string in B , you need to use a library function like strcpy() (or preferably, a safer function, like snprintf() ). 如果要将空字符串存储在B ,则需要使用类似strcpy()的库函数(或者最好使用更安全的函数,如snprintf() )。 In this case, you could also just assign \\0 to B[0] , since that's the same thing. 在这种情况下,您也可以只将\\0分配给B[0] ,因为那是同一回事。 In C and C++, you can't assign arrays (or C strings, which are just arrays of characters) using = . 在C和C ++中,不能使用=分配数组(或C字符串,它们只是字符数组)。

Ideally, you should just use std::string instead of raw C strings; 理想情况下,您应该只使用std::string而不是原始C字符串; then you don't have to worry about this sort of thing. 那么您不必担心这种事情。

The problem is that when you tried to do: 问题是,当您尝试执行以下操作时:

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

you are copying over readonly data - which is not a good idea. 您正在复制只读数据-这不是一个好主意。 That's because the pointer, C, points to a string literal; 这是因为指针C指向字符串文字; overwriting string literals is not allowed. 不允许覆盖字符串文字。 Similar comments apply to B - but there you are also leaking memory. 类似的注释也适用于B-但您也会泄漏内存。

The key point is the comment you made about 'run time' not 'compile time' error. 关键是您对“运行时”而不是“编译时”错误的评论。 It is not that the member is inaccessible; 这并不是说该成员不可访问。 it is just not abusable when you've initialized it as you have. 初始化后,它只是不可滥用的。

The error is in the line: 错误在该行中:

C = "test";

in mystruct's constructor. 在mystruct的构造函数中。 "test" is a pointer to read-only memory, it's not safe to use it to initialize a non-const pointer. "test"是指向只读内存的指针,使用它初始化非const指针并不安全。 The only reason the compiler doesn't enforce this is the huge amount of C code created before people cared about const-correctness, which ought to be declared const but aren't. 编译器不执行此操作的唯一原因是,在人们关注const正确性之前创建了大量的C代码,应该将其声明为const但实际上并不是。

B = "";

is likewise not type-safe. 同样不是类型安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM