23. december 2009 - 19:16Der er
38 kommentarer og 1 løsning
C++ Hukommelses allokering
Hej eksperter,
Jeg har lavet en kode som laver en hukommelses blok med plads til 2 heltal. Problemet er bare at når jeg så sætter hver hukommelses plads til et heltal, så kan jeg også sætte et tal å plads 3 og der op af, selvom jeg kun har allokeret plads til 2.
Derefter reallokerer jeg så der kun er plads til 1 heltal, og tildeler derefter et heltal til 3 pladser mere, stadig ingen access violation. Dt fprstår jeg ikke?
int main() { int a; int b[1]; a = 123; b[1] = 456; printf("%d\n", a); return 0; }
Principielt kan der ske hvad som helst naar det koerer, men typisk vil der ske en af 3:
* det crasher fordi b[1] er et sted i memory som man ikke har adgang til * det udskriver 456 fordi b[1] er a * det udskriver 123 fordi b[1] er et validt sted i memory forskelligt fra a
Hvis du spoerger om hvorvidt realloc naar arrayet bliver mindre altid vil genbruge pladsen d.v.s. ikke aendrer pointeren, saa tvivler jeg - C plejer at overlade den slags til implementationen, men for at vaere sikker vil jeg skulle checke C standarden og POSIX stanrdarden.
og lige et spørgsmål mere: Når jeg bruger realloc til at reducere array´ets størrelse til 1 vil data allokeret på pladserne 2 og 3 osv. blive frigjrt for andre applikationer samt sat til 0?
C programmer opererer på virtuel hukommelse. Hver applikation har sit eget virtuelle adresserum. Memory som frigives via free eller realloc er virtuel hukommelse som frigives til anden brug i samme applikation. Styresystemet håndterer så mapningen fra virtuel hukommelse til RAM og page file og allokerer RAM og page fil mellem de forskellige applikationer.
Hukommelsen bliver ikke nødvendigvis sat til nul ved frigivelse. Den bliver ikke engang nødvendigvis sat til nul ved allokering med malloc eller realloc !
Man skal bruge calloc for at være sikker på at det er nul.
Hvorfor er det ikke godt at reducere Capacity ved Remove? Hvad nu hvis det er et system med meget lidt hukommelse. Jeg går ud fra at realloc frigiver hukommelsen, når man reducerer størrelsen på array'et.
Du skriver: undgå at assigne til variable i argumenter, det gør koden meget svær at følge Skal jeg så overloade kontruktøren, så man kan initialisere både med og uden specifikation af ønsket capacity?
Angående Reverse funktionen, så har jeg siddet og glukket lidt på den, og det ser ikke ud til at det bliver meget bedre det jeg er kommet frem til. Jeg ville være glad for en uddybning her :)
Min GetType funktion returnere størrelsen på den type man har gang i :) Jeg kunne nemlig ikke tænke mig til en smartere løsning?
realloc frigiver hukommelsen til C RTL (d.v.s. til nye malloc/new kald), men formentlig ikke til OS.
Argumentet for ikke at gøre det er at: - sandsynligvis er den hukommelses mængde vi snakker om ubetydelig - sandsynligvis skal der tilføjes senere, så den her frigivelse resulterer sandsynligvis i et stort antal kopieringer frem og tilbage fordi Capacity hele tiden ændres
Det vil sige at jeg bare skal hive tildelingen af capacity ud, så det er mere læsbart, og lave tildelingen ovenover?
Jeg må indrømme at din pseudo kode til reverse funktionen forvirrer mig lidt, men det er nok fordi jeg har siddet i loddetinsrøg hele dagen ;) (Det er midnat ;))
Jeg har nogle flere spørgsmål :)
Hvis jeg skal bruge nøgelordene new og delete, hvordan kan jeg så lave min insert funktion hvis jeg ikke måtte bruge malloc, memmove osv?
Hvis jeg allokerer sådan her: char * chars = new char[100]; // Allokere plads til hundrede
hvis jeg så lige bagefter går sådan her: chars = new char[200]; // Allokere plads til 200
Kommer der så plads til 300? Og er det så det samme som at bruge realloc, og kan man godt reducerer char array'et f.eks sådan her: char * chars = new char[100]; chars = new char[10];
puha det var mange spørgsmål ;)
Men hvis man ikke spørger lærer man ikke en skid ;)
Det vil sige at jeg bare skal hive tildelingen af capacity ud, så det er mere læsbart, og lave tildelingen ovenover?
Ja.
Hvis jeg skal bruge nøgelordene new og delete, hvordan kan jeg så lave min insert funktion hvis jeg ikke måtte bruge malloc, memmove osv?
Hvis jeg allokerer sådan her: char * chars = new char[100]; // Allokere plads til hundrede
hvis jeg så lige bagefter går sådan her: chars = new char[200]; // Allokere plads til 200
Kommer der så plads til 300? Og er det så det samme som at bruge realloc, og kan man godt reducerer char array'et f.eks sådan her: char * chars = new char[100]; chars = new char[10];
Nej. En new er en malloc ikke en realloc. Så du vil selv skulle kopiere.
Jeg må indrømme at din pseudo kode til reverse funktionen forvirrer mig lidt, men det er nok fordi jeg har siddet i loddetinsrøg hele dagen ;) (Det er midnat ;))
Eksempel:
#include <iostream> #include <string>
using namespace std;
template<typename T> void reverse(T *a, int n) { for(int i = 0; i < n/2; i++) { T tmp = a[i]; a[i] = a[n - 1 - i]; a[n - 1 - i] = tmp; } }
template<typename T> void print(T *a, int n) { for(int i = 0; i < n; i++) { cout << a[i] << endl; } }
int main() { X *a = new X[3]; X *b = new X[2]; for(int i = 0; i < 2; i++) b[i] = a[i]; delete[] a; for(int i = 0; i < 2; i++) b[i].M(); delete[] b; return 0; }
Jeps, jeg må indrømme at jeg ikke kan se logikken i koden, ikke fordi den er forkert, men nok fordi min hjerne ikke kan kapere hukommelses programmering i det hele taget. Jeg lukker, bukker og takker for hjælpen arne ;)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.