C ++全局char指针?

时间:2011-12-25 03:31:10

标签: c++ pointers char global

我正在制作的大型程序的一部分需要从命令行读入并存储在类中的路径。因为路径可以是任意大小,并且在多个函数中需要它,所以我将它存储在头文件中的char*中。但是,出于某种原因,当我为它分配一个值时,程序会出现段错误。

调试器(gdb)显示以下内容:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b4828a in std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char> >&, char*) ()
   from /usr/lib/libstdc++.so.6

这是我写的用来演示问题的程序:

TEST.CPP:

#include "test.h"

#include <iostream>
#include <cstring>

Test::Test() {
  filepath = NULL;
}

void Test::set_path(char* string) {
  char temp[strlen(string) + 1];
  strcpy(filepath, temp);
}

char * Test::get_path() {
  return filepath;
}

int main(int argc, char *argv[]) {
  std::cout << "Enter a file path: ";
  char *temp;
  std::cin >> temp;
  Test *temp2 = new Test();
  temp2->set_path(temp);
  std::cout << "Path: " << temp2->get_path() << std::endl;
}

test.h:

#ifndef TEST_H
#define TEST_H

class Test {
private:
  char *filepath;

public:
  Test();
  void set_path(char *);
  char * get_path();
};

#endif // TEST_H

我不确定它崩溃的原因。我正在做这个方法有什么问题吗?此外,我不想只切换到string,而是想了解更多有关此问题的信息。

提前致谢!

3 个答案:

答案 0 :(得分:3)

temp(在main内)未初始化且未指向任何有效的已分配内存块,因此行:

std::cin >> temp;

导致输入被写入内存的某个未知部分,导致未定义的行为。你应该:

  • temp成为char[],只读取适合缓冲区的字符数。
  • temp指向有效的缓冲区。
  • 更好,将temp设为std::string,让std::string课程担心内存管理问题。


解决上述问题后,您还会遇到与filePath类似的问题。在filePath构造函数中,NULL被设置为Test,然后您将temp复制到filePath指向Test::set_path的内存块中{1}}:

strcpy(filepath, temp);

NULL指的是您不允许取消引用的地址。您应该将所有C字符串更改为std::string并使用std::string成员函数和重载运算符来处理C ++中的字符串。

答案 1 :(得分:1)

您调用strcpy而不为set_path中要复制的字符串分配内存。手册页明确指出dest必须足够大才能包含src中的字符串。除了你从一个空的临时复制。虽然,当您从cin读取未初始化的指针时,您的崩溃会提前出现。

使用std::string

#include <iostream>

class Foo
{
public:
  Foo(const std::string& s) : s_(s) {} ;
private:
  std::string s_;
};

int main()
{
  std::string f;
  std::cin >> f;
  std::cout << f << std::endl;
  Foo foo = Foo(f);
  return 0;
}

如果你确实喜欢你在做什么:

class Foo
{
public:
  Foo(const char* s) {
    size_t size = strlen(s);
    s_ = new char[size + 1];
    // safer
    strncpy(s_, s, size + 1);
  } ;
private:
  char* s_;
};

int main()
{
  char buffer[1024];
  // be save
  buffer[1023] = '\0';
  Foo foo = Foo(buffer);
  return 0;
}

第二个例子仍然破裂。它缺少一个正确的析构函数,复制构造函数和赋值运算符。我会留下这个练习。

答案 2 :(得分:0)

Test::Test() {
  filepath = NULL;
}

void Test::set_path(char* string) {
  char temp[strlen(string) + 1];
  strcpy(filepath, temp);
}

我不确定你认为strcpy将要做什么,但它做的是将temp(未初始化)复制到filepath,这是NULL。所以这两个参数都没有任何意义。