Błąd "stack buffer overflow"

Błąd "stack buffer overflow"
Julia Kim
  • Rejestracja:ponad 2 lata
  • Ostatnio:ponad 2 lata
  • Postów:2
0

Przy debugowaniu w Visual Studio kompilator pokazuje, że jest błąd

Kopiuj
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
#include <fstream>
#include <string>
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int main() {

    // Declaring and initializing variables
    int a_min = 1, a_max = 5;
    int b_min = -7, b_max = 7;
    int c_min = -10, c_max = 10;
    int x, a, b, c;

    //Arrays for a, b and c
    int array_a[2];
    int array_b[2];
    int array_c[2];

    srand(time(NULL));

    // GENERATING RANDOM NUMBERS FOR a, b and c

    for (int i = 0; i < 3; i++) {
        a = a_min + rand() % a_max;
        b = b_min + rand() % (b_max - b_min + 1);
        c = c_min + rand() % (c_max - c_min + 1);

        // Saving values in arrays 
        array_a[i] = a;
        array_b[i] = b;
        array_c[i] = c;
    }

    //Printing saved values in arrays 
    //Just to know what we have and to compare the results.

    cout << "\n \n DATA IN THE ARRAYS \n \n";
    for (int i = 0; i < 3; i++) {
        cout << "a" << i << " ";
        cout << array_a[i] << " ";
    }
    cout << endl;
    for (int i = 0; i < 3; i++) {
        cout << "b" << i << " ";
        cout << array_b[i] << " ";
    }
    cout << endl;

    for (int i = 0; i < 3; i++) {
        cout << "c" << i << " ";
        cout << array_c[i] << " ";
    }
    cout << endl;

    cout << "---------------------- \n" << endl;

    //Multiplying the values of the arrays by each argument

    for (int x = -10; x <= 10; x++) { //itarating the range -10 to 10

        for (int i = 0; i < 3; i++) {
            cout << x * array_a[i] << " ";
        }
        cout << endl;

        for (int i = 0; i < 3; i++) {
            cout << x * array_b[i] << " ";
        }
        cout << endl;

        for (int i = 0; i < 3; i++) {
            cout << x * array_c[i] << " ";
        }
        cout << endl << endl;
        cout << endl << endl;
    }
   
    return 0;
}
edytowany 3x, ostatnio: Riddle
Riddle
@Julia Kim: Umieszczaj całośc Twojego kodu w znaczniki formatujące kod ```c++ oraz ```. Możesz też zaznaczyć kod i użyć przycisku </> na pasku narzędzi.
kq
A jak "pokazuje że jest błąd", to wypadałoby też przekazać jaki, żebyśmy nie musieli zgadywać.
Marius.Maximus
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 14 godzin
  • Postów:2098
1

Twoja wersja https://godbolt.org/z/dcEMoaMKx

Kopiuj
 =================================================================
 ==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd24020218 at pc 0x000000401f4f bp 0x7ffd240201b0 sp 0x7ffd240201a8
 WRITE of size 4 at 0x7ffd24020218 thread T0
     #0 0x401f4e in main /app/example.cpp:36
     #1 0x7fadbf261082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
     #2 0x401ffd in _start (/app/output.s+0x401ffd)

Poprawiona
https://godbolt.org/z/M7rjnWYGa


--
Nie przyjmuję reklamacji za moje rady, używasz na własną odpowiedzialność.
Programowanie bez formatowania to jak chodzenie ze spodniami spuszczonymi na kostki. Owszem da się ale po pierwsze nie wygodne, po drugie nieprzyzwoicie wygląda.
Przed zaczęciem nowego wątku przeczytam problem XY
edytowany 1x, ostatnio: Riddle
Riddle
@Adamek Adam: Nie osadzaj outputów z narzędzi w cytat, raczej użyj do tego ```.
Marius.Maximus
@Riddle zakodowałem ! outputy to też kod , dziekuje za uwagę
Riddle
@Adamek Adam: Nie ważne czy uważamy go za kod czy nie kod; ważne jest że chcemy je pokazać 1:1 - formatowanie ``` zachowuje treść. W cytatach uruchamiane jest formatowanie 4programmers, i znaki *, [, _ mogłyby zostać niepoprawnie wyświetlone. Dodatkowo w ``` mamy czcionkę monospace.
EM
  • Rejestracja:około 4 lata
  • Ostatnio:ponad 2 lata
  • Postów:6
0

Z tego co widzę, w Twoim programie występuje błąd w pętli for w liniach 42, 45 i 48. Pętla for ma iterować przez zakres od -10 do 10, ale w każdej z tych linii pętla iteruje przez trzy elementy tablic array_a, array_b i array_c. To może spowodować nieoczekiwane wyniki lub błędy w działaniu programu.

Aby naprawić ten błąd, zamiast iterowania przez trzy elementy tablic, należy zamienić pętlę for w każdej z tych linii na pętlę for, która będzie iterować przez cały zakres od -10 do 10. W ten sposób program będzie działać poprawnie.

Oto jak można to naprawić:

Kopiuj
//Multiplying the values of the arrays by each argument

for (int x = -10; x <= 10; x++) { //itarating the range -10 to 10

    for (int i = -10; i <= 10; i++) {
        cout << x * array_a[i] << " ";
    }
    cout << endl;

    for (int i = -10; i <= 10; i++) {
        cout << x * array_b[i] << " ";
    }
    cout << endl;

    for (int i = -10; i <= 10; i++) {
        cout << x * array_c[i] << " ";
    }
    cout << endl << endl;
    cout << endl << endl;
}
edytowany 1x, ostatnio: Riddle
_13th_Dragon
Czego się naćpałeś?
ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
1

@Adamek Adam: @EMUSING
Bosch co za dziwny wątek ... wy tu z armat do much stzrelacie, a pierwszy problem widze już przez niedzielną niedoszła drzemkę

Julia Kim napisał(a):

Przy debugowaniu w Visual Studio kompilator pokazuje, że jest błąd

Kopiuj
    int array_a[2];
    for (int i = 0; i < 3; i++) {
        array_a[i] = a;
    }

Chłopy, to ja zaćpany widzę na kilometr.

@Julia Kim:

Musisz mieć w palcach zakodowane, że jak masz tablicę zadeklartowaną z rozmiarem "iks", to pętle robisz z warunkie i < "iks"

Tu konkretnie, tablica ma wymiar dwa, elementy mają indeksy a[0], a[1]
A pętlą przetwarzasz trzy a[0], a[1], a[2]
W konsekwencji, niszczysz coś, co jest w następnej komórce

C jest kiepskim językiem do dydaktyki, bo błędy nie przejawiają się "na twardo", kara nie jest natychmiastowa i precyzyjna, ale dają Undefined Behaviour, czyli może się nic nie ujawnić, może ci zgasnąć prąd, rozmrozić lodówka, albo może polecieć stack uverflow (choć częściej poleci inny wyjątek systemowy)


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
edytowany 3x, ostatnio: Riddle
ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
0
Adamek Adam napisał(a):

Poprawiona
https://godbolt.org/z/M7rjnWYGa

Poprawiona tak naprawdę nie jest poprawiona, specjalnie zaszedłem w ten link.

Kopiuj
for (int i = 0; i < 3; i++) {
    cout << x * array_a[i] << " ";
}

Zamieniłeś ostrą postać błędu na bardziej subtelną.

Sorry Kolego, ale kod trzeba czytać, a nie puszczać lintery czy inne automaty i bałwochwalczo brać ich wyniki

(a że C jest językiem d/d to inna sprawa)

@EMUSING:

Pięknie jeździsz -10 ... 10 po 2 elementowej tablicy


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
edytowany 4x, ostatnio: Riddle
MarekR22
Adamek Adam zmienił wielkość tablicy, a nie pętlę i w ten sposób naprawił problem czytania poza tablicą.
ZD
Czyli zmienił semantykę kodu a nie porpawił
MarekR22
Ja nie potrafię z przekonaniem powiedzieć co ten kod tak naprawdę ma robić. A ty?
ZD
Prawda. Kod jest dziwny, i trudno wstecznie ocenić, co miałoby być jego celem. Ja się zasugerowałem, że jest świadomy zamysł w wielkości tablicy
ZD
Dobre pytanie. Jakoś tak "od zawsze" się zakłada, ze rozmiar tablicy jest OK, tam nie ma czarów, a błędna pętla (jest nieintuicyjne o jeden nizej) - nie sądzicie ?. Choć sam sobie dam anty-odpowiedż: bufor na C-string bez nulla, popularny błąd początkujących
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:5 dni
0

Jeżeli zrobić tablicę dwuwymiarową 3x3 to da się zmniejszyć ilość kodu (czyli oszczędzić sporo czasu), czyli zamiast twoich 26 wierszy mamy:

Kopiuj
int randrange(int min,int max) { return min+rand()%(max-min+1); }

int main()
{
	srand(time(0));
	const int ValueCount=3;
	const int SampleCount=3;
	struct {int min,max; } ranges[ValueCount]={{1,5},{-7,7},{-10,10}};
	int args[SampleCount][ValueCount];
	for(int s=0;s<SampleCount;++s)
	{
		for(int v=0;v<ValueCount;++v) args[s][v]=randrange(ranges[v].min,ranges[v].max);
	}
    //...
    return 0;
}

Jak widzę a,b,c oraz x to mi się kojarzy z a*x^2+b*x^1+c*x^0 czyli:

Kopiuj
    for(int x=-10;x<=10;++x)
    {
        cout<<"x="<<x;
		for(int s=0;s<SampleCount;++s)
		{
			int y=0;
			for(int v=0;v<ValueCount;++v) y=y*x+args[s][v];
			cout<<"\ty"<<(s+1)<<"="<<y<<";";
		}
		cout<<endl;
	}

z tym że istnieje pewna szansa że się mylę.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 2x, ostatnio: _13th_Dragon

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.