【问题标题】:How to fix 'Segmentation Error' when there are no pointers?没有指针时如何修复“分段错误”?
【发布时间】:2019-09-21 03:06:50
【问题描述】:

当我编译我的代码时,它可以正常编译,没有错误,但是当我运行代码时,它给出了以下错误“分段错误”,没有更多信息。但是,当我查看 Segmentation Fault 时,它通常与指针有关,而我根本没有使用过指针。

我已经检查了整件事是否有任何拼写错误,我可能会说“&”而不是“&&”等等。我也查看了错误,并重新编译了代码。

#include <iostream>
#include <vector>

std::string answer(int placement, std::vector<int> peopleInLinE, int Fifties, int twentyFives)
{
  if (((peopleInLinE[placement] - 25) % (Fifties * 50)) == 0)
  {
    Fifties -= peopleInLinE[placement] / (Fifties * 50);
  } else if (((peopleInLinE[placement] - 25) % (twentyFives * 25)) == 0)
  {
    twentyFives -= peopleInLinE[placement] / (twentyFives * 25);
  } else if (peopleInLinE[placement] == 100)
  {
    if (Fifties >= 1 && twentyFives >= 1)
    {
      Fifties -= 1;
      twentyFives -= 1;
    } else if (twentyFives >= 3)
    {
      twentyFives -= 3;
    } else {
      return "NO";
    }
  } else {
    return "NO";
  }
  return "YES";
}

std::string tickets(const std::vector<int> peopleInLine){
  int twentyFiveS;
  int FiftieS;

  for (int placemenT; peopleInLine.size(); placemenT++)
  {
    if (answer(placemenT, peopleInLine, FiftieS, twentyFiveS) == "NO") {
      return "NO";
    }
  }
  return "YES";
}
int main() {
  std::cout << tickets({25, 50, 100, 25});
  return 0;
}

之所以有几个变量有随机大写,是因为我不知道是不是说这两个东西拼写完全一样,所以它们是一样的东西,所以我改了拼写试试想办法解决。

此代码用于 Codewars 上的“Vasya - Clerk”挑战,我包含了整个文件,因为我不知道错误可能出在哪里。

我得到的唯一错误信息是“Segmentation Fault”,没有其他解释。

【问题讨论】:

  • 这是什么for (int placemenT; peopleInLine.size(); placemenT++)
  • 你是在问为什么它有奇怪的大写字母?
  • placemenT也有不确定值,因为你没有初始化它,如果peopleInLine.size() &gt; 0还有一个无限循环,你可能想要for (int placemenT = 0; placemenT &lt; peopleInLine.size(); placemenT++)
  • 我看到@user3365922 非常感谢。
  • 我在编译它时收到许多关于未初始化变量的警告。先解决这些问题,它可能会起作用。

标签: c++ segmentation-fault


【解决方案1】:
int twentyFiveS;
int FiftieS;

这些变量的值不确定,因为您没有初始化它们。读取不确定的值具有未定义的行为。

if (answer(placemenT, peopleInLine, FiftieS, twentyFiveS) == "NO") {

在这一行中,您将不确定值的副本传递给函数。程序的行为未定义。

 for (int placemenT; peopleInLine.size(); placemenT++)

在这一行中,您增加了一个不确定的值,这也是未定义的行为。此外,循环结束条件是错误的,因为peopleInLine的大小在程序中永远不会改变,因此不能达到零。

所以你是说我需要给变量添加一个特定的值(即 int twoFiveS = 0; int FiftieS = 0; ?

如果你想使用它们的值,你必须用一些值来初始化它们。如果您希望该值为 0,则将其初始化。

placemenT 必须至少初始化为一个值,该值是peopleInLinE 的有效索引,否则行为仍将是未定义的。您还必须确保循环结束,然后才能越界访问向量。

【讨论】:

  • “永不终止的循环也有未定义的行为。”真的吗?
  • 所以你是说我需要为变量添加一个特定的值(即int twentyFiveS = 0; int FiftieS = 0; ?
  • @user3365922 我改写了更精确的措辞,但基本上是的。
  • @jwjbadger 如果你想使用它们的值,你必须用一些值初始化它们。如果您希望该值为 0,则初始化为该值。
  • Loops that unconditionally cannot terminate also have undefined behaviour 真的吗?不会终止的循环只会永远运行,那里没有 UB
【解决方案2】:

Address Santizier 是你的朋友。

$ g++ -ggdb3 -O0 so.cpp -fsanitize=address
$ ./a.out
AddressSanitizer:DEADLYSIGNAL
=================================================================
==8680==ERROR: AddressSanitizer: SEGV on unknown address 0x60200002002c (pc 0x555f1b4fd438 bp 0x7fffe57487f0 sp 0x7fffe57486d0 T0)
==8680==The signal is caused by a READ memory access.
    #0 0x555f1b4fd437 in answer[abi:cxx11](int, std::vector<int, std::allocator<int> >, int, int) /tmp/so.cpp:6
    #1 0x555f1b4fd9cc in tickets[abi:cxx11](std::vector<int, std::allocator<int> >) /tmp/so.cpp:36
    #2 0x555f1b4fdd83 in main /tmp/so.cpp:43
    #3 0x7f9c60e6beda in __libc_start_main (/lib64/libc.so.6+0x23eda)
    #4 0x555f1b4fd249 in _start (/tmp/a.out+0x2249)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/so.cpp:6 in answer[abi:cxx11](int, std::vector<int, std::allocator<int> >, int, int)
==8680==ABORTING

问题是您使用未初始化的变量 (placemenT) 作为 peopleInLine 的索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 2018-07-20
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2012-09-04
    相关资源
    最近更新 更多