Ошибка сегментации до достижения основной - C ++ - PullRequest
3 голосов
/ 10 октября 2019

Я пишу код, чтобы найти правильный ввод, который будет генерировать определенный вывод для хеш-функции SHA-1.

Проблема, с которой я сталкиваюсь, состоит в том, что мой код вызывает ошибку сегментации,но gdb обнаруживает, что при вводе main() и перед выполнением любого другого кода возникает следующая ошибка:

Program received signal SIGSEGV, Segmentation fault.
__strncpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:636
636 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.

Это мой код:

#include <iostream>
#include <cstdlib>
#include <cstring>

#include "sha1.hpp"

int main() {
    char *prefix = "SHA1sha1";
    char *suffix = "chicken and beer";
    std::string hashvalue = "nonzero";
    char *line = "just some dummy string";
    int loop_number = 0;

    while (hashvalue.c_str()[0] != '0' || hashvalue.c_str()[1] != '0') {
        // change prefix
        strncpy(prefix, hashvalue.c_str(), 8);
        // hash the concatenated string of prefix and suffix
        strncpy(line, prefix, 8);
        strncat(line, suffix, strlen(suffix));
        hashvalue = sha1(line);

        loop_number++;
        if (loop_number % 1000 == 0) std::cout << loop_number << "th loop, hash value: " << hashvalue << std::endl;
    }

    std::cout << "Found prefix: " << prefix << " with hash value: " << hashvalue << std::endl;

    return 0;
}

sha1.hpp не был реализован мной, но был взят отсюда: http://www.zedwood.com/article/cpp-sha1-function

Я изменил sha1.h на sha1.hpp, но это, вероятно, не то, что вызывает ошибку сегментации.

Теперь у меня есть попытка поиска решения этой проблемы с сообщением об ошибке, а также с ключевыми словами "ошибка сегментации перед основным", и в этом посте, похоже, возникают похожие проблемы: СегментацияНеисправность перед основным

Однако я рассмотрел два предложенных решения, но не смог найти подходящее мне.

  1. Не думаю, чтомой код имеет слишком много переменных в тон укладывает. На самом деле я попытался закомментировать с использованием функции sha1() на всякий случай, но возникла та же проблема.

  2. Я инициализировал все char* и std::string в моем кодеперед использованием.

К вашему сведению, я использую g++ для компиляции своих кодов C ++.

Любая помощь или толчок в нужном направлении будет принята с благодарностью.

Ответы [ 2 ]

4 голосов
/ 10 октября 2019

Вы изменяете неизменяемое содержимое.

// change prefix
strncpy(prefix, hashvalue.c_str(), 8);
// hash the concatenated string of prefix and suffix
strncpy(line, prefix, 8);
strncat(line, suffix, strlen(suffix)); 

Попробуйте изменить объявление, как показано ниже.

char prefix[100] = "SHA1sha1";
char suffix[200] = "chicken and beer";
char line[200] = "just some dummy string

Кроме того, я думаю,

while (hashvalue.c_str()[0] != '0' || hashvalue.c_str()[1] != '0') {

должно быть

while (hashvalue.c_str()[0] != '0' && hashvalue.c_str()[1] != '0') {

Обновление:

Закон де Моргана гласит:

not (A and B) = not A or not B

Опять же, это выбор индивидуума использовать любую формуони хотят

4 голосов
/ 10 октября 2019

Строковые литералы имеют типы постоянных символьных массивов в C ++, и любая попытка изменить строковый литерал приводит к неопределенному поведению. Вы пытаетесь изменить строковый литерал хотя бы в следующем выражении:

strncpy(prefix, hashvalue.c_str(), 8);

Вместо строковых литералов следует использовать массивы символов или объекты типа std::string.

Обратите внимание наэто;например, это if утверждение

while (hashvalue.c_str()[0] != '0' || hashvalue.c_str()[1] != '0') {

можно записать гораздо проще:

while (hashvalue[0] != '0' || hashvalue[1] != '0') {

, хотя кажется, что условие не имеет смысла. Может быть, вы имеете в виду следующее

while ( hashvalue.size() > 1 ) {

Также вам нужно включить заголовок <string>

#include <string>
...