Paweł Nowicki

Paweł Nowicki Oracle Developer

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Dawno nie pracowałem w C, a ostatnio dostałem kilka zadań do zrobienia. Mam problem, najprawdopodobniej z przydzielaniem pamięci i jej zwalnianiem. Pod kompilatorem Microsoft Visual C++ 2008 Express Edition wszystko działa ok do momentu zwalniania pamięci, a pod DevC++ pojawiają błędy sporadycznie wcześniej, ale już nie wiem co może być przyczyną [przykładowa seria danych: 7,7,8,9, lub, 7,9,8,7,8,9..]

treść zadania:

Napisz program, w którym utworzysz w sposób dynamiczny dwuwymiarowa tablice o zadanej z klawiatury
liczbie wierszy n. Dla ka$dego wiersza program pozwala ustalic z klawiatury liczbe kolumn (z zakresu 1–
80). Wypełnij tablice kolejnymi liczbami całkowitymi, poczawszy od 1 i wypisz ja na ekranie.
Przykładowo, dla n = 3 oraz kolumn k1=1, k2=2, k3=3 na ekranie powinno sie znalezc:
1
2 3
4 5 6

mój kod:

#include <iostream>
#include <stdio.h>
#include <conio.h>

using namespace std;
// ####### FUNKCJE #########
int* add_kol_2_row(int i, int &licznik){
//kolumna
int k=0;
while(!((k>=1) && (k<=80))){
cout << " Podaj liczbe kolumn w wierszu " << i+1 << ": ";
cin >> k;
cout << "\n";
}

int* kolumny;
kolumny= new int[k];
kolumny[0]=k; //dopisuje na początku kolumny
// informacje o jej dlugosci

for(int i=1;i<=k;i++){//uzupełnianie kolejnymi liczbami
kolumny[i]=licznik;
(licznik)++;//zwiększanie licznika
}

return kolumny;//zwraca adres do kolumn
}

int show_row(int* row , int i){

for(int i=1;i<=row[0];i++){
cout << row[i] << " ";
}
cout << "\n" ;

return 0;
}

int del_row(int* row){
delete [] row;
return 0;
}
// ###### endFUNKCJE ######


int main ()
{
int n=0;

cout << "p.2.1.\nWprowadz liczbe \'n\'. Program utworzy tabele o wymiarze \'n\'. \n";
cin >> n;
cout << "\n";

int** tablica;
int licznik=1;//początek wypełniania od tej liczby
tablica= new int* [n];

for(int i=0;i<n;i++){//dodawanie kolejnych wierszy
tablica[i] = add_kol_2_row(i, licznik);
}

for(int i=0;i<n;i++){//wyświetlanie wierszy
show_row(tablica[i], i);
}


getch();
// ###### ZWALNIANIE PAMIĘCI ######
/*
for(int i=0;i<n;i++){//zwalnianie pamieci kolumn
del_row(tablica[i]);
}*/

delete [] tablica; //zwalnianie pamieci wierszy

return 0;
}
Paweł Nowicki edytował(a) ten post dnia 28.10.08 o godzinie 09:54

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Allokujesz 'k' kolumn, a uzywasz k+1.

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

. nvm, napisalem to samo co powyzej w tym samym czasie ;pRobert Mituniewicz edytował(a) ten post dnia 28.10.08 o godzinie 10:41
Paweł Nowicki

Paweł Nowicki Oracle Developer

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

faktycznie,
zmieniałem już to, ale być może się zaplątałem, bądź cofnąłem zmiany
wielkie dzięki za pomoc.

jakieś uwagi co do stylu pisania programu?
Tomasz Kaczanowski

Tomasz Kaczanowski Ot, programista

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Paweł Nowicki:
faktycznie,
zmieniałem już to, ale być może się zaplątałem, bądź cofnąłem zmiany
wielkie dzięki za pomoc.

jakieś uwagi co do stylu pisania programu?

Tak - nie jest to ani c ani c++ tylko jakiś potworek. podowiem, jeśli już korzystasz z c++ to:
1) nie #include <stdio.h> a #include <cstdio>
2) możesz użyć pojemników danych z biblioteki standardowej, czyli wektorow, list, itp....

konto usunięte

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Paweł Nowicki:
jakieś uwagi co do stylu pisania programu?


#include <conio.h>


Niestandardowe. Naprawde konieczne?Tomasz Krzos edytował(a) ten post dnia 28.10.08 o godzinie 11:22
Jakub L.

Jakub L. Programista

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Z rzędami jest to samo co z kolumnami, czyli overrrun o jeden element za przydzieloną pamięć.
Po drugie - wiem ze kompiler jest w stanie to zoptymalizować, ale różnica pomiędzy prefiksowym a postfiksowym operatorem ++ się kłania.

A tak ogólnie to #include <vector>, #include <iostream> i polecieć na wektorach i strumieniami.
Tomasz Kaczanowski

Tomasz Kaczanowski Ot, programista

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Jakub L.:
Z rzędami jest to samo co z kolumnami, czyli overrrun o jeden element za przydzieloną pamięć.
Po drugie - wiem ze kompiler jest w stanie to zoptymalizować, ale różnica pomiędzy prefiksowym a postfiksowym operatorem ++ się kłania.

Przy typach standardowych - a tu takie w zasadzie występuja - różnicy nie ma.
Jakub L.

Jakub L. Programista

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Tomasz Kaczanowski:
Jakub L.:
Z rzędami jest to samo co z kolumnami, czyli overrrun o jeden element za przydzieloną pamięć.
Po drugie - wiem ze kompiler jest w stanie to zoptymalizować, ale różnica pomiędzy prefiksowym a postfiksowym operatorem ++ się kłania.

Przy typach standardowych - a tu takie w zasadzie występuja - różnicy nie ma.

Jak dla mnie to http://www.parashift.com/c++-faq-lite/operator-overloa... jest wystarczającym wytłumaczeniem.
Te operatory mają inną semantykę, ale jak się nie odbiera ich wyniku, to kompilator ma pole do popisu.

konto usunięte

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Jakub L.:
Te operatory mają inną semantykę, ale jak się nie odbiera ich wyniku, to kompilator ma pole do popisu.
??? chyba nie rozumiem

konto usunięte

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Jakub L.:
różnica pomiędzy prefiksowym a postfiksowym operatorem ++ się kłania.
W tym konkretnym przypadku nie ma zadnej roznicy.
Jesli sie mysli o wydajnosci nalezy zaprzatac sobie glowe ++pre i post++ tylko i wylacznie w przypadku obiektow w ktorych je zaimplementowano (tworzy sie obiekt tymczasowy). Dla arytmetycznych typow prostych nie ma to zadnego znaczenia.Piotr P. edytował(a) ten post dnia 29.10.08 o godzinie 05:00

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Jakub L.:
Jak dla mnie to http://www.parashift.com/c++-faq-lite/operator-overloa... jest wystarczającym wytłumaczeniem.
Te operatory mają inną semantykę, ale jak się nie odbiera ich wyniku, to kompilator ma pole do popisu.
Jak sie odbiera to tez roznicy nie bedzie. Ot, cos a'la:
inc eax
mov ebx, eax
zamiast
mov ebx, eax
inc eax
Jakub L.

Jakub L. Programista

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

No dobra, rzeczywiście nie potrafię napisać kodu który dawałby tutaj inną liczbę menmoników.
Pozostanę jednak przy swoim że wolę widzieć ++a niż a++, chociażby po to, żeby mieć jedną rzecz w palcach i nie musieć pamiętać że jak to typ prosty, to mogę jak chcę, a jak obiekt to mam uważać.

konto usunięte

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Jakub L.:
Pozostanę jednak przy swoim że wolę widzieć ++a niż a++, chociażby po to, żeby mieć jedną rzecz w palcach i nie musieć pamiętać że jak to typ prosty, to mogę jak chcę, a jak obiekt to mam uważać.
A tu sie zgadzam :)
Robie dokladnie tak samo, ze tak powiem, ze wzgledow estetycznych.Piotr P. edytował(a) ten post dnia 30.10.08 o godzinie 06:34

konto usunięte

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Patrzycie na wydajność kodu? a++ lub ++a? Rozwijanie pętli? Autowektoryzacja?Bo z tego, co się orientuję, to dziś optymalizacja wydajności kodu w obliczu gigaherców, ma się źle. Widzi mi się, że dziś ważniejsze jest dotrzymanie terminów niż szybkość kodu. Np. gra MUSI się ukazać przed świętami Bożego Narodzenia. Chodzi wolno? Kupcie sobie Szanowni Klienci lepszy sprzęt!

konto usunięte

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Tomasz Krzal:
Widzi mi się, że dziś ważniejsze jest dotrzymanie terminów niż szybkość kodu.
Termin to jedno, ale jakosc kodu to drugie.

Nie zgadzam sie, ze optymalizacja ma sie zle.
Mam jeszcze nawyki optymalizacji z dawnych czasow.
Z pol roku temu zaczalem sprawdzac pewne sprawy, jak to wyglada na poziomie asemblera. Poza pewnymi przypadkami (objekty tymczasowe, funkcje wirtualne itd) mozna dac sobie spokoj z mysleniem o optymalizacji - zdecydowana wiekszosc zalatwia za nas kompilator, naprawde dobrze optymalizuje.
Znalazlem tylko jeden przypadek gdy kompilator zrobil to gorzej ode mnie, ale i to nie jestem do konca pewnien.
Obecnie programista powinien bardziej sie skupic na logice programu i uzywanych algorytmow i jeszcze kilku innych przypadkach (np. inicjacja zmiennych klasy w liscie konstruktora).

Dotyczy to przynajmniej gnu/gcc.
Byc moze w niszowych obszarach, na specyficznych systemach, kompilatory nie sa takie madre.Piotr P. edytował(a) ten post dnia 30.10.08 o godzinie 13:30

konto usunięte

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Piotr P.:
Nie zgadzam sie, ze optymalizacja ma sie zle.
Mam jeszcze nawyki optymalizacji z dawnych czasow.
Z pol roku temu zaczalem sprawdzac pewne sprawy, jak to wyglada na poziomie asemblera. Poza pewnymi przypadkami (objekty tymczasowe, funkcje wirtualne itd) mozna dac sobie spokoj z mysleniem o optymalizacji - zdecydowana wiekszosc zalatwia za nas kompilator, naprawde dobrze optymalizuje.

Nie chciałbym wywoływać tu flame-u, ale dam tu kontrprzykłady:
1) "Hello world" pod asm 32-bit i pod C/C++ mają kod wynikowy różniący się wielkościami wiele razy,
2) Systemy operacyjne pisane tylko w asm (np. MenuetOS), mają wielkość taką, że na dyskietce 1.44MB zostaje jeszcze trochę miejsca. Są to systemy wielozadaniowe, z obsługą inetu, itd.
3) Jest taka gierka jak kKrieger (dwa 'k' na początku), która zajmuje 96kB i której czas trwania i jakość grafiki są POWALAJĄCE w stosunku do wielkości jej pliku.

To są przykłady świadczące wg mnie o tym, że dziś kompilatory optymalizują dobrze, ale schematycznie. Schematycznie, bo semantyczna optymalizacja (czyli można powiedzieć: skrajna refaktoryzacja) to jest zadanie dziś TYLKO dla programisty.

konto usunięte

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Tomasz Krzal:
Piotr P.:
Nie zgadzam sie, ze optymalizacja ma sie zle.
Mam jeszcze nawyki optymalizacji z dawnych czasow.
Z pol roku temu zaczalem sprawdzac pewne sprawy, jak to wyglada na poziomie asemblera. Poza pewnymi przypadkami (objekty tymczasowe, funkcje wirtualne itd) mozna dac sobie spokoj z mysleniem o optymalizacji - zdecydowana wiekszosc zalatwia za nas kompilator, naprawde dobrze optymalizuje.

Nie chciałbym wywoływać tu flame-u, ale dam tu kontrprzykłady:
1) "Hello world" pod asm 32-bit i pod C/C++ mają kod wynikowy różniący się wielkościami wiele razy,
2) Systemy operacyjne pisane tylko w asm (np. MenuetOS), mają wielkość taką, że na dyskietce 1.44MB zostaje jeszcze trochę miejsca. Są to systemy wielozadaniowe, z obsługą inetu, itd.
3) Jest taka gierka jak kKrieger (dwa 'k' na początku), która zajmuje 96kB i której czas trwania i jakość grafiki są POWALAJĄCE w stosunku do wielkości jej pliku.

To są przykłady świadczące wg mnie o tym, że dziś kompilatory optymalizują dobrze, ale schematycznie. Schematycznie, bo semantyczna optymalizacja (czyli można powiedzieć: skrajna refaktoryzacja) to jest zadanie dziś TYLKO dla programisty.
W tym przypadku nie obwinialbym kompilatora, tylko biblioteki.
Faktem jest ze malenki programik w c/c++ jest duzy, ale pozniej przyrasta juz bardzo powoli.
Juz od jakiegos czasu uwazam, ze najbardziej zaniedbanym narzedziem jest linker (chocby problemy z bibliotekami).Piotr P. edytował(a) ten post dnia 30.10.08 o godzinie 13:55

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

Tomasz Krzal:
3) Jest taka gierka jak kKrieger (dwa 'k' na początku), która zajmuje 96kB i której czas trwania i jakość grafiki są POWALAJĄCE w stosunku do wielkości jej pliku.
Tutaj przeczysz sam sobie, bo kkrieger jest w 90% napisany w C/C++.
Piotr B.

Piotr B. development engineer

Temat: Problem z dynamicznym przydzielaniem pamięci w prostym...

O ile w stwierdzeniu, że terminy dzisiaj są głównymi "batami" nad programistami, to jednak nie jedynymi... podany przykład dotyczył programów pudełkowych, ale zauważcie, że spory procent pracy to wciąż proces, że się tak wyrażę, "informatyzacji spersonalizowanej", czyli tworzenia oprogramowania na zamówienie danej instytucji - i w tym wypadku, o ile terminy nadal istnieją, to jednak dają się przesuwać, natomiast bubel wolny jak cholera zwyczajnie nie przejdzie... Akurat pracuję w większości tylko przy takich projektach - klienci bardzo często dysponują sprzętem sprzed kilku lat i ani myśli go zmieniać (poza może serwerem - ale końcówki mają być takie, jakie są).

Następna dyskusja:

[zagadka] scalenie w czasie...




Wyślij zaproszenie do