【问题标题】:void pointer segmentation fault空指针分段错误
【发布时间】:2019-07-30 00:23:10
【问题描述】:

为了理解 void 指针是如何工作的,我写了一段代码来测试它。但是,我在运行时遇到了分段错误,并且不知道如何处理它。这里的关键点是,数据是在该函数调用内部生成的。您不知道数据类型以及应该分配的 void 指针有多大。

#include <iostream>
#include <vector>

int valueAssignment(void *ptr1, void *ptr2){
  std::vector<int> vi;
  std::vector<double> vb;
  int num = 10;

  for (size_t i = 0; i < num; i++) {
    vi.push_back((int)rand());
    vb.push_back((double)rand());
    std::cerr <<i<<": "<< vi[i] <<'\t'<<vb[i]<<'\n';
  }

  for (size_t i = 0; i < num; i++) ((int*)ptr1)[i] = vi[i];

  for (size_t i = 0; i < num; i++) ((double*) ptr2)[i] = vb[i];

  return num;
}

int main(int argc, char const *argv[]) {

  void * intPtr, *doublePtr;
  int size;

  size = valueAssignment(intPtr,doublePtr);

  std::cerr << "/* ------------------- */" << '\n';

  for (size_t i = 0; i < size; i++) {
    std::cout <<i<<": "<< ((int*)intPtr)[i]<<"," <<((double *)doublePtr)[i]<<std::endl;
  }

  return 0;
}

【问题讨论】:

  • 你需要让这些指针指向有效的内存位置。
  • size = valueAssignment(intPtr,doublePtr); -- intPtrdoublePtr 未初始化,因此这永远无法工作。
  • 在您尝试了解 void 指针之前,请练习使用类型指针,例如int* 如果你不能使用直接的指针,你得到 void 指针的机会很小。它们主要用于“我实际上知道得更好”的情况。
  • "为了理解 void 指针是如何工作的......" 你可能应该阅读good book

标签: c++ pointers pass-by-reference void


【解决方案1】:

我们应该简单地遵循专家给出的许多建议。

  1. 不要在 C++ 中使用原始指针
  2. 不要在 C++ 中使用原始指针
  3. 不要在 C++ 中使用原始指针

有了它,我们已经取得了巨大的进步。但是,您想了解void* pointer。 void 指针是一个可以指向任何东西的通用指针。您还可以将其他指针类型分配给 void 指针。反之亦然,这是不可能的,您需要显式类型转换。

对于类和特别是派生类,您甚至可能会因进行此类强制转换而丢失信息。

传统 C 代码经常使用 void 指针,但这基本上没有问题。

在现代 C++ 中,很少需要 void 指针。也许主要是为了与遗留代码交互。

那么,现在来看看你的特殊情况:

这个问题已经在很多 cmets 中提到过。这与 void 指针无关,而是一般的指针。您的指针未初始化。它们指向某个地方,随机地指向内存中的某个点。在您的子函数中,您正在为那些未初始化的指针分配值,将值随机写入内存中的某个位置。你的程序会崩溃。

因此,指针需要指向已定义的某个位置。到定义的内存区域。

你可以写:

    int intArray10[10];        // You should not use C-Style plain arrays
    double doubleArray10[10];  // You should not use C-Style plain arrays

    void* intPtr = intArray10;
    void* doublePtr = doubleArray10;

然后您的指针将指向一个已定义的区域。你的程序会工作。

但是你想在你的函数中以某种方式定义或使用指针。如果大小已知,则可以使用new 分配数据并将其分配给指针。然后必须将指针作为“对指针的引用”或“指向指针的指针”传递。如果不知道尺寸会比较困难,需要告知调用程序尺寸。

所有这些都非常容易出错,应该避免。

再说一遍:不要使用原始指针。如果您确实需要它们来管理资源,请使用std::unique_ptrstd::shared_ptr

或者最好首先使用 STL 容器。

【讨论】:

    猜你喜欢
    • 2021-04-09
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 2013-09-18
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    相关资源
    最近更新 更多