C++全局字符指针

C++ global char pointer?

本文关键字:指针 字符 全局 C++      更新时间:2023-10-16

我正在制作的更大程序的一部分需要从命令行读入路径并存储在类中。由于路径可以是任意大小,并且在多个函数中都需要它,因此我将其存储在头文件的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

这是我为演示问题而编写的程序:

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

测试.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,而是想了解更多关于这个问题的信息。

提前感谢!

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

std::cin >> temp;

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

  • 使temp成为char[],并且仅读取缓冲区中适合的字符量。
  • temp指向有效的缓冲区。
  • 更好的是,让temp成为std::string,让std::string类担心内存管理。


解决上述问题后,您也会遇到类似的filePath问题。 filePathTest 构造函数中设置为NULL,然后temp复制到 filePath in Test::set_path 中指向的内存块:

strcpy(filepath, temp);

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

调用 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] = '';
  Foo foo = Foo(buffer);
  return 0;
}

第二个例子仍然被打破。它缺少正确的析构函数、复制构造函数和赋值运算符。我将把它作为一个练习。

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

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