简体   繁体   English

通过指针访问char *

[英]Accessing a char* through a pointer

here is my problem. 这是我的问题。

I have a class that regularly modifies a char*. 我有一个定期修改char *的类。

There is another class, that needs to be able to read this value. 还有另一个类,需要能够读取该值。 So I want to pass the char* to the constructor of this second class, so that it can check the value, when required. 因此,我想将char *传递给第二个类的构造函数,以便在需要时可以检查该值。

Let me give an example of the implementation that I have for another parameter, it is of a type boolean: 让我举一个我为另一个参数实现的例子,它是布尔类型:

In ClassA: 在ClassA中:

bool f_valid = false; // global

m_eventCatcher.addProxy(porting::shared_ptr<CallbackProxy>(new handleCall(&f_valid))); 

In ClassB: 在ClassB中:

struct handleCall 
{
    bool* m_dataValid;

    handleCall(bool* result) 
    {
        // saving the pointer to the boolean that I want to change
        m_dataValid = result; 
    }

    method()
    {
        if (smth) 
        { 
            (*m_dataValid) = false;
        }
    }
};

So far so good - this seems to work. 到目前为止,一切都很好-这似乎可行。 Both classes can change and access this boolean. 这两个类都可以更改和访问此布尔值。

Now I need to do the same thing with a char* (I cannot use string, so I guess this is a best way to store a short text, like a url address?). 现在,我需要对char *做同样的事情(我不能使用字符串,所以我想这是存储短文本(如url地址)的最佳方法吗?)。

So here is what I wrote: 所以这是我写的:

ClassA: A类:

const char* f_url = "blah blah"; // global

m_eventCatcher.addProxy(porting::shared_ptr<CallbackProxy>(new handleCall2(&f_url)));

ClassC: ClassC:

struct handleCall2 
{
    char ** m_url;

    handleCall2(char** url)
    {
        // saving the pointer to the char*
        m_url= url;
        std::cout << (*m_url) << std::endl; // prints out url fine
    }

    method() 
   {
        std::cout << (*m_url) << std::endl; // by this time the value has been changed by ClassA, and I print out some rubbish - symbols, squares, etc.
    }
};

I guess the problem is because the string has changed, its' address has changed too? 我猜问题是因为字符串已更改,其地址也已更改? I am getting really confused - can someone tell me what is going on, and what should I do in this situation? 我真的很困惑-有人可以告诉我发生了什么,在这种情况下我该怎么办?

UPDATE: 更新:

Looks like the problem is in HOW I modify the char*: 看起来问题出在我如何修改char *:

f_url = "new text"; // works fine

f_url = fileUrl.c_str(); // doesn't work! I get rubbish in the value when I try to access it from ClassB

strcpy(m_url, fileUrl.c_str()); // I also removed const from the variable and tried this - got a crash "access violation using location" :(

Is there any other way of writing the value of a string into a char *? 还有其他将字符串的值写入char *的方法吗?

const char* f_url = "blah blah";

this declaration means that you have a pointer to a constant string. 此声明意味着您有一个指向常量字符串的指针。 So you can't do 所以你做不到

strcpy(f_url, "hello world"); // copy to the preallocated place

but you can 但是你可以

f_url = "hello world"; // do pointer assignment

If you have next situation : 如果您有下一种情况:

class ClassA {
const char* f_url = "blah blah";
public: 
    void method() {
        f_url = "hello world";
    }
};

class ClassB {
    char** m_url;
public:
    void print() {
        cout << (* m_url); // m_url points to a string, allocated on the stack of ClassA::method()
    }
};

keep in mind that string "hello world" is allocated on the stack of the ClassA::method() . 请记住,字符串"hello world"分配在ClassA::method()的堆栈上。 And that pointer is no longer valid when the ClassA::method() quits. 并且当ClassA::method()退出时,该指针不再有效。 to solve the issue I propose next: 为了解决我接下来提出的问题:

class ClassA {
static const int max_path = 256; 
char f_url[max_path];
public: 
    void method() {
        strcpy(f_url, "hello world");
    }
};

class ClassB {
    char** m_url;
public:
    void print() {
        cout << (* m_url);
    }
};

I do not see any problem with accessing a char * . 访问char *不会出现任何问题。

I wrote a sample code and it worked for me. 我写了一个示例代码,它对我有用。 May be yours is a different issue: 可能是您的问题不同:

BTW here is my code for your reference: 顺便说一句,这是我的代码供您参考:

#include <iostream>

class ClassThatPrints
{
private:
    const char **m_url;

public:
    ClassThatPrints(const char ** url)
    {
        m_url = url;
        std::cout << (*m_url) << std::endl;
    }

    void PrintAfterModify(void)
    {
        std::cout << (*m_url) << std::endl;
    }
};

class ClassThatModifies
{
private:
    const char *m_charPointer;
    ClassThatPrints *m_ClassThatPrints;
public:
    ClassThatModifies()
    {
        m_charPointer = "this is the original string";
        std::cout << "Printing before modification:" << std::endl;
        m_ClassThatPrints = new ClassThatPrints(&m_charPointer);
    }

    ~ClassThatModifies() {
        delete m_ClassThatPrints;
    }

    void ModifyStringAndPrint(void)
    {
        m_charPointer = "this is a modified string";
        std::cout << "Printing after modification:" << std::endl;
        m_ClassThatPrints->PrintAfterModify();
    }
};

int main()
{
    ClassThatModifies objClassThatModifies;
    objClassThatModifies.ModifyStringAndPrint();

}

If you have something like this: 如果您有这样的事情:

void addHandler() {
    const char* f_url = "blah blah";
    m_eventCatcher.addProxy(porting::shared_ptr<CallbackProxy>(new handleCall2(&f_url)));
}

void doStuff() {
    addHandler();
    m_eventCatcher.callProxy();
}

then the problem is that f_url is out of scope when addHandler returns. 那么问题是当addHandler返回时,f_url超出范围。 If this is the case, then your bool version also had the problem, and (*m_dataValid) = false; 如果是这种情况,那么您的bool版本也有问题,并且(*m_dataValid) = false; overwrote some other data. 覆盖了其他一些数据。

const char* f_url = "blah blah"; // global

Maybe you misunderstand this line? 也许您误会了这条线? The const qualifier is when you are placing it, referring to the keyword left of it. const限定词是放置它时,指代其左侧的关键字。 It's allowed to take it as first keyword but then, AND ONLY then, it is referring to its right ;) So your declaration says: (const char) *f_url so its an pointer to an const char. 允许将其作为第一个关键字,但是,然后,仅然后,它指的是它的权利;)因此,您的声明说:(const char)* f_url因此它是指向const char的指针。 And I'm guessing (I don't know what's the way you are modifying it's value in that class) you get it by your self, why modifying a const char value could end in rubbish output, don't you? 而且我猜(我不知道您在该类中修改它的值的方式是什么)是您自己获得的,为什么修改const char值可能会导致垃圾输出,不是吗? I suggest you want to declare it as 我建议您将其声明为

char *const f_url = "blah blah";

this is 这是

char (* const) f_url 字符(* const)f_url

so f_url is an constant address-value which is pointing into an modifiable area. 因此f_url是指向修改区域的常量地址值。 But even this wouldn't make that much sense, because "blah blah" is a address of a const memory area, so you cant modify ("blah blah")[count] = Anything; 但是,即使这样也没有多大意义,因为“等等”是const存储区的地址,因此您无法进行修改(“等等”)[count] =任何内容; anyway. 无论如何。

So you should just do 所以你应该做

char *const f_url = ThisIsACharArray[count];

and access the char array aka String about f_url. 并访问有关f_url的char数组(也称为String)。

Or the better way for you, as I would guess, just keep the const out of the declaration and allocate modifiable memory by your self ;) 或者,对我来说,更好的方法是,将const保留在声明之外,并自行分配可修改的内存;)

The string is not actually stored in f_url . 该字符串实际上没有存储在f_url The string is stored somewhere else , and f_url is a pointer to that somewhere else . 该字符串存储在其他位置 ,而f_url是指向其他位置的指针。

If you do this: 如果您这样做:

    f_url = "new text"; // works fine

When your program is compiled it will include the string "new text" somewhere in it. 编译程序时,它将在其中的某个位置包含字符串"new text" f_url will point to that - to some memory in the middle of the program itself. f_url将指向该位置-指向程序本身中间的一些内存。


    f_url = fileUrl.c_str(); // doesn't work! I get rubbish in the value when I try to access it from ClassB

fileUrl is a std::string. fileUrl是一个std :: string。 fileUrl has its own pointer to a string, which c_str returns. fileUrl有自己的指向字符串的指针,c_str返回该字符串。 Since fileUrl is in responsible for managing this string, when fileUrl goes out of scope the memory may be reused for something else - it doesn't know you were still using that memory. 由于fileUrl负责管理此字符串,因此当fileUrl超出范围时,内存可能会被其他用途重用-它不知道您仍在使用该内存。


    // I assume you meant f_url here, not m_url
    strcpy(f_url, fileUrl.c_str()); // I also removed const from the variable and tried this - got a crash "access violation using location" :(

What this does depends on what f_url is actually pointing to. 它的作用取决于f_url实际指向的内容。 If f_url is pointing to some memory in the middle of your program (as with f_url = "blah blah"; ) then this will crash. 如果f_url指向程序中间的某些内存(如f_url = "blah blah"; ),则会崩溃。 Normally, this indicates a bug, so the operating system will not allow you to do it. 通常,这表明存在错误,因此操作系统将不允许您这样做。

If it was allowed, this could happen: 如果允许,则可能发生:

char *s = "hello world";
strcpy(s, "abracadabra");

printf("hello world"); // prints "abracadabra"


What you need to do is get your own block of memory to hold the string, and free it when you are done: 您需要做的是获取自己的内存块来保存字符串,并在完成后释放它:

f_url = new char[fileUrl.length() + 1];
strcpy(f_url, fileUrl.c_str());

// when you don't need the string any more
delete [] f_url;

or: 要么:

f_url = strdup(fileUrl.c_str());

// when you don't need the string any more
free(f_url);

or just make f_url a std::string which handles memory management for you. 或者只是将f_urlstd::string来为您处理内存管理。 (This is the easiest solution!) (这是最简单的解决方案!)

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

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