• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zgłoszono wyjątek: naruszenie dostępu do zapisu. v było nullptr.

Object Storage Arubacloud
0 głosów
1,005 wizyt
pytanie zadane 19 listopada 2019 w C i C++ przez bakobydlak Nowicjusz (160 p.)

Witam, potrzebuje pomocy- nie wiem gdzie znajduje sie moj blad przy wskaznikach:

#include "pch.h"
#include <iostream>
#include "sort.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int createTab(int** pTab,int nSize)
{
	*pTab = (int*)malloc(nSize * sizeof(int));
	if (pTab) memset(pTab, 0, nSize * sizeof(int));
	else return 0;
	return 1;
}	
void freeTab(int* pTab)//zwolnij tablice /mallock&memset & czy sie powiodlaelse null
{
	free(pTab);
}
void initTab(int* pTab, int nSize, int nVal)
{
	int *v = pTab; 
	for (int i = 0; i < nSize; i++)
	{
		*v = nVal; //TUTAJ BLAD WSKAZNIKA
		v++;
	}

}
void randomInit(int* pTab, int nSize) //srand&rand //modulo rozmiar -preferencje
{
	
	int *v = pTab;
	time_t tt;
	int zarodek = time(&tt);
	srand(zarodek);   // za zarodek wstawiamy pobrany czas w sekundach
	for (int i = 0; i < nSize; ++i)
	{
		*v = rand() % 999; //zleeeeee
		v++;
	}

void PrintTab(int* pTab, int nSize)
{
	int *v = pTab;
	for (int i = 0; i < nSize; i++)
	{
	printf("%d\t", *v);
	*v++;
	}
	
}
#include "pch.h"
#include <iostream>
#include "sort.h"
#include <stdio.h>

using namespace std;


int* pTab = NULL;
int* pomTab = NULL;

int main()
{
	int nSize = 0;
	printf("Podaj ilosc elementow do posortowania:\n");
	cin >> nSize;

	createTab(&pTab,nSize);
	initTab(pTab, nSize, 0);
	randomInit(pTab, nSize);
	PrintTab(pTab, nSize);
	freeTab(pTab);



	return 0;
}
#ifndef SORT_H
#define SORT_H

void freeTab(int* pTab);//zwolnij tablice /mallock&memset & czy sie powiodlaelse null
void initTab(int*, int nSize, int nVal);
void randomInit(int* pTab, int nSize); //srand&rand //modulo rozmiar -preferencje
void copyTab(int* pTab, int* pTabFrom, int nSize); //kopiuje do tabl z 2 do 1
void PrintTab(int* pTab, int nSize);
int createTab(int** pTab, int nSize);

#endif

 

komentarz 19 listopada 2019 przez tkz Nałogowiec (42,000 p.)
Dlaczego mieszasz C z C++? Ogólnie kod się nie kompiluje bez poprawek. Dlaczego pobierasz wskaźnik na wskaźnik?
komentarz 19 listopada 2019 przez adrian17 Ekspert (345,160 p.)

Ogólnie kod się nie kompiluje bez poprawek

Mi się kompiluje.

Natomiast też nie rozumiem co w kodzie C++owym robi malloc().

No i widać że już w tym createTab() jest błąd powodujący crasha, bo dziwnie żonglujesz tym podwójnym wskaźnikiem.

komentarz 19 listopada 2019 przez tkz Nałogowiec (42,000 p.)
Skopiowałem i brakowało nawiasów.
komentarz 20 listopada 2019 przez niezalogowany
edycja 20 listopada 2019

Czy ktoś mądry wytłumaczy dlaczego alokuje się tablice w funkcji jaki z tego pożytek?

a nie np tak?

int* newTab (int nSize) {
    int *pTab = malloc(nSize * sizeof(int));
    if (pTab) {
        memset(pTab, 0, nSize * sizeof(int));
        return pTab;
    } else
        return NULL;
}

bo zasnąć nie mogę :)

edit:: teraz już tak https://www.reddit.com/r/C_Programming/comments/2wu0i5/is_it_better_to_malloc_inside_a_function_or/

komentarz 20 listopada 2019 przez tkz Nałogowiec (42,000 p.)
Zwracanie NULLa nie jest najlepszym pomysłem.
komentarz 20 listopada 2019 przez j23 Mędrzec (194,920 p.)
A to dlaczego?
komentarz 20 listopada 2019 przez tkz Nałogowiec (42,000 p.)
Uzasadnieniem braku zwracania wartości NULL jest to, że nie trzeba jej sprawdzać, a zatem kod nie musi podążać inną ścieżką w oparciu o wartość zwracaną. Możesz sprawdzić Null Object Pattern, który zawiera więcej informacji. Zwracanie wartości null jest złym podejściem, gdy zamiast tego można zwrócić, powiedzmy, pustą tablicę.
komentarz 20 listopada 2019 przez adrian17 Ekspert (345,160 p.)
Przypominam że jesteśmy w C++ie, używamy new zamiast malloc ;) `new`  przy zwykłym użyciu nie może zwrócić nulla (jeśli nie uda się zaalokować to rzuci wyjątek - a w praktyce we większości programów nieudane alokacje są w ogóle nie obsługiwane, tylko przyjmuje się że automatycznie zamkną program).
1
komentarz 20 listopada 2019 przez j23 Mędrzec (194,920 p.)

@tkz, eee, to dość częsty sposób sygnalizowania "błędu" w C.
 

komentarz 20 listopada 2019 przez niezalogowany
edycja 20 listopada 2019

@adrian17,
 a nie pomyślałem że można rzucić wyjątek.

Staram się na uczyć dobrych praktyk. A narzazie nie mam okazji przejrzeć  "Czystego kodu".

Ale gdzieś czytałem w "Polskim internecie" i rozsądnie było napisane że alokacja pamięci w funkcji, to nie jest najlepszy pomysł i rzadko tego w ogóle używa. Ale może się mylę? A nie chcę zakładać osobnego pytania jak jest okazja podpiąć się pod te.

EDIT::Nie mam tu namyśli ani inteligentnych wskaźników, ani new w klasie, gdzie destruktor posprząta.

komentarz 20 listopada 2019 przez tkz Nałogowiec (42,000 p.)

adrian17 tak nie do końca w C++, trudno stwierdzić po kodzie w czym pisze autor w końcu. 

@tkz, eee, to dość częsty sposób sygnalizowania "błędu" w C.

Jeżeli coś jest częste, nie znaczy, że poprawne. 

Przypominam że jesteśmy w C++ie, używamy new zamiast malloc ;) `new`  przy zwykłym użyciu nie może zwrócić nulla

new (nothrow) nie zgłasza wyjątków i zwróci NULL jeśli alokacja się nie powiedzie. Tylko jeszcze dochodzi co rozumiesz przez "zwykłe użycie".

 

komentarz 20 listopada 2019 przez niezalogowany
"zwykłe użycie" szkoda ze nie pamientam strony, ale autor sadząc po kodach to był zapoznany z językiem, tam akurat c++. Ja nie jestem programistą, ale nie chciałbym jak cokolwiek napiszę, to jeszcze się troczyć poza innymi błędami, że program gubi pamięć. A w C jako takich klas nie ma i przez ponad 10 lat Windows słynął z niebieskich okien, a chyba w C był napisany.
komentarz 20 listopada 2019 przez tkz Nałogowiec (42,000 p.)
Struktury, a klasy odróżnia domyślny modyfikator dostępu. I to chyba tyle z tych różnic.
komentarz 20 listopada 2019 przez adrian17 Ekspert (345,160 p.)

tak nie do końca w C++, trudno stwierdzić po kodzie w czym pisze autor w końcu. 

Jest cin/cout ;)

Tylko jeszcze dochodzi co rozumiesz przez "zwykłe użycie".

Mam na myśli to, że większość programów właśnie nie używa new(nothrow). I też nie owija każdego vector.push_back() w try+catch(bad_alloc) - tylko po prostu w ogóle nie myślą o możliwości nieudanej alokacji, bo i po co.

komentarz 20 listopada 2019 przez niezalogowany
edycja 20 listopada 2019
Ok, nie wiem. Skoro tak piszesz  to pewnie tak jest, nie będę udawał że się znam w C++. Ale w C to trochę trzeba się na gimnastykować by napisać klasę taką jaką w C++. A co do tych praktyk, to chyba i u Praty i w "Symfonii" pewnie też to jest napisane, a to takie fundamenty, a bez fundamentów domu nie będzie.

Edit:: A co do dobrych praktyk to w innej dziedzinie miałem okazję czytać zbiór takich. Na książkę czekało się pół roku. Bo nie nadążyli drukować jak wyszło nowe wydanie. Nie nie w Polsce.
komentarz 20 listopada 2019 przez tkz Nałogowiec (42,000 p.)

https://www.fluentcpp.com/2017/06/13/the-real-difference-between-struct-class/

O jakich fundamentach mówisz dokładnie? 

Zwracanie wartości null jest złym podejściem, gdy zamiast tego można zwrócić, powiedzmy, pustą tablicę.

Powoływałem się na słowa Robert C. Martin, a myślę, że jest jakimś autorytetem w świecie IT.

komentarz 20 listopada 2019 przez niezalogowany
edycja 20 listopada 2019
Ok poczytam, przemyślę i odpowiem, ale to pewnie nie wcześniej niż za miesiąc.

EDIT:: A to co pisze o C strukturze i to sam próbowałem wyklepać rozbudowaną strukturę  i no i nie było tak łatwo i przyjemnie. Ale to może wynikać z mojej nie znajomości C w tym zakresie.

Ps. A źródło fajne, bardzo dużo tam ciekawych rzeczy. Tylko ten czas :(;
komentarz 20 listopada 2019 przez adrian17 Ekspert (345,160 p.)

Zwracanie wartości null jest złym podejściem, gdy zamiast tego można zwrócić, powiedzmy, pustą tablicę.

(Um... to raczej jest javowa rada? Bo W C++ie ona raczej nie ma sensu. Ale to już raczej nie jest temat na ten wątek, więc jak ktoś chce ciągnąć to PM)

komentarz 20 listopada 2019 przez tkz Nałogowiec (42,000 p.)

adrian17  jak na wszystko, to zależy...

komentarz 20 listopada 2019 przez mokrowski Mędrzec (155,660 p.)
1. Co do zasady, w C++ nie używa się malloc. Zresztą szereg metodyk tego zabrania (branża lotnicza, medyczna, automotive).

2. Co do "manualnej alokacji pamięci" (tak dla C jak i C++), zaleca się by alokacja i zwolnienie pamięci, odbywała się na tym samym poziomie abstrakcji. Czyli funkcja która alokuje, powinna (o ile to możliwe), zwalniać pamięć przed wyjściem z niej. (CERT Secure Coding Standards).

3. Co do sygnalizowania null'em braku alokacji, dla C jest to rzecz normalna. Dla C++ są lepsze sposoby (np. std::optional).

4. Od reguł są wyjątki. Np. Qt ma odmienną filozofię alokacji narzucaną przez framework.

5. Jest możliwość (choć powinna być wybierana z ostrożnością), by alokować dane poprzez argument przekazywany a poprzez return sygnalizować efekt działania. W wielu przypadkach taki kod może być mało czytelny. Czasem takie funkcje obejmuje dany standard (np. NVIDIA dla CUDA czy Khronos dla OpenCL robi to nagminnie). Dla C skutkuje to argumentem podwójnego wskaźnika.

1 odpowiedź

0 głosów
odpowiedź 20 listopada 2019 przez bakobydlak Nowicjusz (160 p.)
Dzieki za rady - ogolnie to sie sam uczylem troche c++ troche c ,a ze visual kompiluje jedno z drugim to smiga :D. U mnie osobiscie nie zadzialalo przez memset w createtab. Po odkomentowaniu program smiga

Podobne pytania

0 głosów
0 odpowiedzi 3,825 wizyt
0 głosów
1 odpowiedź 1,643 wizyt
0 głosów
1 odpowiedź 320 wizyt
pytanie zadane 6 czerwca 2022 w C i C++ przez kacper1445 Gaduła (4,880 p.)

92,620 zapytań

141,474 odpowiedzi

319,813 komentarzy

62,004 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...