通过指针访问char *

时间:2013-08-09 11:13:45

标签: c++ c pointers char-pointer

这是我的问题。

我有一个定期修改char *的课程。

还有另一个类,需要能够读取此值。所以我想将char *传递给第二个类的构造函数,以便它可以在需要时检查值。

让我举一个我对另一个参数的实现的例子,它的类型为boolean:

在ClassA中:

bool f_valid = false; // global

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

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

到目前为止一直很好 - 这似乎有效。这两个类都可以更改并访问此布尔值。

现在我需要用char *做同样的事情(我不能使用字符串,所以我想这是存储短文本的最佳方式,比如url地址?)。

所以这就是我写的:

ClassA的:

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

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

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

我猜问题是因为字符串已经改变,它的'地址也改变了?我真的很困惑 - 有人能告诉我发生了什么,在这种情况下我该怎么做?

更新:

看起来问题出在我如何修改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" :(

有没有其他方法可以将字符串的值写入char *?

5 个答案:

答案 0 :(得分:0)

const char* f_url = "blah blah";

此声明表示您有一个指向常量字符串的指针。所以你做不到

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

但你可以

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

如果你有下一个情况:

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()
    }
};

请记住,"hello world"的堆栈上分配了字符串ClassA::method()。当ClassA::method()退出时,该指针不再有效。解决我接下来提出的问题:

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

答案 1 :(得分:0)

我认为访问char *没有任何问题。

我写了一个示例代码,它对我有用。可能是你的另一个问题:

BTW这是我的代码供您参考:

#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();

}

答案 2 :(得分:0)

如果你有这样的事情:

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();
}

然后问题是当addHandler返回时f_url超出范围。 如果是这种情况,那么你的bool版本也有问题,(*m_dataValid) = false;覆盖了其他一些数据。

答案 3 :(得分:0)

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

也许你误解了这一行? const限定符是在你放置它时,引用它左边的关键字。 它被允许作为第一个关键字,然后,然后,只有它,它指的是它的权利;) 所以你的声明说:(const char)* f_url 所以它是一个指向const char的指针。 而且我猜(我不知道你在修改它在该类中的价值的方式是什么)你自己得到它,为什么修改一个const char值可以以垃圾输出结束,不是吗? 我建议您将其声明为

char *const f_url = "blah blah";

这是

  

char(* const)f_url

所以f_url是一个指向可修改区域的常量地址值。 但即使这样也没那么有意义,因为“blah blah”是const内存区域的地址,所以你不能修改     (“blah blah”)[count] =任何东西; 反正。

所以你应该这样做

char *const f_url = ThisIsACharArray[count];

并访问char数组,即关于f_url的String。

或者更好的方式,正如我猜测的那样,只需将const保留在声明之外,并为自己分配可修改的内存;)

答案 4 :(得分:0)

该字符串实际上并未存储在f_url中。该字符串存储在其他地方,而f_url是指向其他地方的指针。

如果你这样做:

    f_url = "new text"; // works fine

编译程序时,会在其中的某处包含字符串"new text"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是一个std :: string。 fileUrl有自己的指向字符串的指针,c_str返回。由于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" :(

这取决于f_url实际指向的内容。如果f_url指向程序中间的某些内存(与f_url = "blah blah";一样),则会崩溃。通常,这表示存在错误,因此操作系统不允许您这样做。

如果允许,可能会发生这种情况:

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

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


你需要做的是获取你自己的内存块来保存字符串,并在完成后释放它:

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;

或:

f_url = strdup(fileUrl.c_str());

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

或只是让f_url成为std::string,为您处理内存管理。 (这是最简单的解决方案!)

相关问题