/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
bliver pladsen frigjort?
Fra : Bjarke Walling Peter~


Dato : 26-05-02 16:53

Det kan godt være jeg er en smule 'low level', men hvis man nu absolut _vil_
have en funktion der returnerer en pointer til en null-terminated string
(altså char *) - bliver pladsen som strengen optager i rammen frigjort når
programmet slutter eller skal man lave nogle fiksfakserier for at dette
bliver gjort - i så fald hvilke?

Et eksempel kunne være:

#include <iostream>
using namespace std;

char *funktion(unsigned int x)
{
char *str;
str = new char(x+1); // Selvfølgelig burde man også checke at x!=0 og
str ikke bliver sat til NULL
for (int i=1; i<x-1; i++) {
str[i]='-';
}
str[0] = '<';
str[x-1] = '>';
str[x] = '\0';
return str;
} // Tag jer ikke af at funktionen egentlig ikke kan bruges til noget
fornuftigt!

int main(int argc, char *argv[])
{
cout << funktion(10) << endl;
return 0; // Bliver strengen jeg oprettede i 'funktion' nu frigjort fra
rammen?
}

Håber nogen kan hjælpe mig.

Mvh. Bjarke



 
 
Martin Moller Peders~ (26-05-2002)
Kommentar
Fra : Martin Moller Peders~


Dato : 26-05-02 17:39

In <3cf104da$0$70409$edfadb0f@dspool01.news.tele.dk> "Bjarke Walling Petersen" <bwp@bwp.dk> writes:

>Det kan godt være jeg er en smule 'low level', men hvis man nu absolut _vil_
>have en funktion der returnerer en pointer til en null-terminated string
>(altså char *) - bliver pladsen som strengen optager i rammen frigjort når
>programmet slutter eller skal man lave nogle fiksfakserier for at dette
>bliver gjort - i så fald hvilke?

Alle operativsystem boer frigive alt plads, som et program har brugt, naar det afsluttes og det sker da ogsaa
for baade Linux og Windows.

MVh
Martin




Bjarke Walling Peter~ (26-05-2002)
Kommentar
Fra : Bjarke Walling Peter~


Dato : 26-05-02 18:01

Martin Moller Pedersen skrev:
> Alle operativsystem boer frigive alt plads, som et program har brugt, naar
det afsluttes og det sker da ogsaa
> for baade Linux og Windows.

Okay, tak for svaret. Jeg troede blot at det var mit program, der allokerede
pladsen - ikke at den sendte besked til Windows om at der skulle allokeres
noget plads.

Mvh. Bjarke



Rasmus Kaae (26-05-2002)
Kommentar
Fra : Rasmus Kaae


Dato : 26-05-02 19:36

"Bjarke Walling Petersen" <bwp@bwp.dk> wrote in message
news:3cf114e1$0$70377$edfadb0f@dspool01.news.tele.dk...
> Martin Moller Pedersen skrev:
> > Alle operativsystem boer frigive alt plads, som et program har brugt,
naar
> det afsluttes og det sker da ogsaa
> > for baade Linux og Windows.
>
> Okay, tak for svaret. Jeg troede blot at det var mit program, der
allokerede
> pladsen - ikke at den sendte besked til Windows om at der skulle allokeres
> noget plads.

uhm, malloc/calloc/new bruger såvidt jeg ved alle GlobalAlloc fra Win32API
og en ligeledes funktion til free/delete/whatever



Michael Rasmussen (26-05-2002)
Kommentar
Fra : Michael Rasmussen


Dato : 26-05-02 20:57

> uhm, malloc/calloc/new bruger såvidt jeg ved alle GlobalAlloc fra Win32API
> og en ligeledes funktion til free/delete/whatever

jeg tror den bruger HeapAlloc, men det er også ligemeget for:
<msdn>
The GlobalAlloc function allocates the specified number of bytes from the
heap. In the linear Win32 API environment, there is no difference between
the local heap and the global heap.
</msdn>

-- Michael Rasmussen



Martin Moller Peders~ (26-05-2002)
Kommentar
Fra : Martin Moller Peders~


Dato : 26-05-02 19:44

In <3cf114e1$0$70377$edfadb0f@dspool01.news.tele.dk> "Bjarke Walling Petersen" <bwp@bwp.dk> writes:

>Martin Moller Pedersen skrev:
>> Alle operativsystem boer frigive alt plads, som et program har brugt, naar
>det afsluttes og det sker da ogsaa
>> for baade Linux og Windows.

>Okay, tak for svaret. Jeg troede blot at det var mit program, der allokerede
>pladsen - ikke at den sendte besked til Windows om at der skulle allokeres
>noget plads.

Ingen programmer kan allokere hukommelse selv. Det sker altid gennem et kerne-kald dvs. gennem operativ-
systemet.

Mvh
Martin




Kent Friis (26-05-2002)
Kommentar
Fra : Kent Friis


Dato : 26-05-02 21:11

Den Sun, 26 May 2002 18:43:43 +0000 (UTC) skrev Martin Moller Pedersen:
>In <3cf114e1$0$70377$edfadb0f@dspool01.news.tele.dk> "Bjarke Walling Petersen" <bwp@bwp.dk> writes:
>
>>Martin Moller Pedersen skrev:
>>> Alle operativsystem boer frigive alt plads, som et program har brugt, naar
>>det afsluttes og det sker da ogsaa
>>> for baade Linux og Windows.
>
>>Okay, tak for svaret. Jeg troede blot at det var mit program, der allokerede
>>pladsen - ikke at den sendte besked til Windows om at der skulle allokeres
>>noget plads.
>
>Ingen programmer kan allokere hukommelse selv. Det sker altid gennem et kerne-kald dvs. gennem operativ-
>systemet.

Medmindre man kører DOS...

Mvh
Kent
--
Hvis man ikke kan lide klassisk musik, er det sandsynligvis fordi
lydkvaliteten er for dårlig. Klassisk musik kræver et godt anlæg.

Michael Rasmussen (26-05-2002)
Kommentar
Fra : Michael Rasmussen


Dato : 26-05-02 22:36

> >Ingen programmer kan allokere hukommelse selv. Det sker altid gennem et
kerne-kald dvs. gennem operativ-
> >systemet.
>
> Medmindre man kører DOS...

hvorfor skulle det være anderledes med DOS?

-- Michael Rasmussen



Kent Friis (27-05-2002)
Kommentar
Fra : Kent Friis


Dato : 27-05-02 18:01

Den Sun, 26 May 2002 23:35:31 +0200 skrev Michael Rasmussen:
>> >Ingen programmer kan allokere hukommelse selv. Det sker altid gennem et
>kerne-kald dvs. gennem operativ-
>> >systemet.
>>
>> Medmindre man kører DOS...
>
>hvorfor skulle det være anderledes med DOS?

Fordi DOS ikke indholder nogen form for beskyttelse mod at programmer
skriver hvor de har lyst.

Mvh
Kent
--
Linux 0.12 is out
Windows XP is now obsolete!!!

Michael Rasmussen (27-05-2002)
Kommentar
Fra : Michael Rasmussen


Dato : 27-05-02 18:57

"Kent Friis" <leeloo@phreaker.net> wrote in message
news:actonq$jgh$1@sunsite.dk...
> Fordi DOS ikke indholder nogen form for beskyttelse mod at programmer
> skriver hvor de har lyst.

nej, men derfor bliver hukkommelsen da alligevel allokeret gennem
kernekald - enten til DOS-extenderen eller vha. int 21h kald.

-- Michael Rasmussen



Kent Friis (27-05-2002)
Kommentar
Fra : Kent Friis


Dato : 27-05-02 19:06

Den Mon, 27 May 2002 19:56:33 +0200 skrev Michael Rasmussen:
>"Kent Friis" <leeloo@phreaker.net> wrote in message
>news:actonq$jgh$1@sunsite.dk...
>> Fordi DOS ikke indholder nogen form for beskyttelse mod at programmer
>> skriver hvor de har lyst.
>
>nej, men derfor bliver hukkommelsen da alligevel allokeret gennem
>kernekald - enten til DOS-extenderen eller vha. int 21h kald.

>>> Ingen programmer kan allokere hukommelse selv.

Det var den jeg svarede på. Jeg er faktisk ikke sikker på hvordan memory
allokering "officielt" foregår under DOS, jeg mente faktisk at man
automatisk havde hele hukommelsen fra starten af programmet og op.

Der er SVJH noget med at man skal huske at frigive hukommelse, hvis et
program skal kalde et andet program. Damn, det er længe siden jeg legede
med turbo-pascal.

Mvh
Kent
--
Mails skrevet før 12:00 skal læses med det forbehold, at hjernen først
forventes at være færdig med at boote på det tidspunkt, og indholdet
derfor kan indeholde random data der tilfældigvis lå i den
uinitializerede cache.

Michael Rasmussen (27-05-2002)
Kommentar
Fra : Michael Rasmussen


Dato : 27-05-02 20:18


"Kent Friis" <leeloo@phreaker.net> wrote in message
news:actshv$1c$1@sunsite.dk...
> >>> Ingen programmer kan allokere hukommelse selv.
>
> Det var den jeg svarede på. Jeg er faktisk ikke sikker på hvordan memory

jowjow, det var jeg nu godt klar over :)

> allokering "officielt" foregår under DOS, jeg mente faktisk at man
> automatisk havde hele hukommelsen fra starten af programmet og op.

tja, det er vel som man ser på det, du *kan* principielt tilgå al
hukommelsen
når programmet er startet op, men det vil (læs: bør) et velopdragent
DOS-program ikke
gøre.

men det er vel egentlig ikke voldsomt aktuelt mere, så pyt.

-- Michael Rasmussen



Mogens Hansen (27-05-2002)
Kommentar
Fra : Mogens Hansen


Dato : 27-05-02 21:34


"Martin Moller Pedersen" <tusk@daimi.au.dk> wrote

[snip]
> Ingen programmer kan allokere hukommelse selv. Det sker altid gennem et
kerne-kald dvs. gennem operativ-
> systemet.

Forkert.
I C++ bliver hukommelse dynamisk allokeret med "operator new" og frigivet
"operator delete" (i forskellige varianter) (Der findes også andre
funktioner f.eks. malloc/free).
Der er intet krav om at der nedenunder disse funktioner ligger kerne-kald
til et operativsystem. Mere generelt kræves det ikke at der findes et
operativsystem for at køre et program skrevet i C++. Hvis der er et operativ
system kaldes det "hosted" implementering, og ellers en "freestanding"
implementering - se C++ Standarden §1.4 og §17.4.1.3
Det er intet til hinder for at lave et embedded system, der umiddelbart
efter CPU er blevet startet, kører lidt initialiseringskode og derefter
hopper direkte til main. I sådan et system kan det være hådtkodet (f.eks. i
link konfigurationen), hvor meget hukommelse der er til rådighed, og hvilket
adresse-rum det befinder sig på. Oven på den information kan man "bare" lave
en heap manager (det vil typisk følge med compileren).
Den slags systemer findes.

Venlig hilsen

Mogens Hansen



Niels Teglsbo (27-05-2002)
Kommentar
Fra : Niels Teglsbo


Dato : 27-05-02 22:52

"Mogens Hansen" <mogens_h@dk-online.dk> wrote:

> Den slags systemer findes.

Og bruges blandt andet til at skrive kerner med på DIKU. Selvom det er
lidt hemmeligt hvordan man får ting som new og virtual til at virke, men
malloc og free er en smal sag. Man tager bare nogle MB hukommelse og
bruger dem som hob (via malloc og free). Og så sørger man selv for ikke
at bruge den del af hukommelsen til andet.

--
Niels, The Offspring Mailinglist www.image.dk/~teglsbo

Thomas Lykkeberg (26-05-2002)
Kommentar
Fra : Thomas Lykkeberg


Dato : 26-05-02 19:29

On Sun, 26 May 2002 17:52:48 +0200, "Bjarke Walling Petersen"
<bwp@bwp.dk> wrote:

>Det kan godt være jeg er en smule 'low level', men hvis man nu absolut _vil_
>have en funktion der returnerer en pointer til en null-terminated string
>(altså char *) - bliver pladsen som strengen optager i rammen frigjort når
>programmet slutter eller skal man lave nogle fiksfakserier for at dette
>bliver gjort - i så fald hvilke?
Alt som bliver allokeret med malloc() skal frigives med free(), alt
der bliver allokeret med GlobalAlloc(), skal frigives med GlobalFree()
og slutteligt alt der allokeres med new skal frigives med delete.

char *ptr;
ptr = (char *)malloc(sizeof(char)*10);
....
free(ptr);


char *ptr;
ptr = new char(10);
....
delete char;

og så fremdeles...

Hvis du arbejder i C++ kan du jo lave en klasse i stedet for en
funktion. Her kunne kontruktøren så allokerer pladsen til strengen med
new og destruktøren kunne så frigive pladsen igen med delete, når
objektet bliver "nedbrudt".

Det er sikkert rigtigt (= jeg er ikke sikker på det sker i alle
tilfælde), når det bliver sagt at Windows/Linux frigiver pladsen igen,
men det er så absolut ikke den pæne måde at gøre tingene på.

Hvis du eksempel vis kalder din funktion 100 gange i et programforløb,
vil programmet (inden det afsluttes) have lagt beslag på en mængde
hukommelse som sikkert ikke skal bruges til noget, og dette vil jo
ikke blive frigjort før programmet afsluttes.

Det er nu en generel regl at man frigiver allokeret hukommelse igen,
lige så snart man ikke skal bruge det mere, så andre processer kan få
nytte af det.

/Thomas

Bjarke Walling Peter~ (26-05-2002)
Kommentar
Fra : Bjarke Walling Peter~


Dato : 26-05-02 20:16

Thomas Lykkeberg skrev:
[snip]
> Hvis du arbejder i C++ kan du jo lave en klasse i stedet for en
> funktion. Her kunne kontruktøren så allokerer pladsen til strengen med
> new og destruktøren kunne så frigive pladsen igen med delete, når
> objektet bliver "nedbrudt".

Ja, det ved jeg ... jeg benytter dem ofte.
Selvom det var af ren nysgerrighed jeg stilte spørgsmålet, er jeg kommet på
et evt. problem angående frigørelse af hukommelse (det er ikke noget problem
jeg selv har lige nu!). F.eks. lad os sige jeg har en klasse MyClass og at
jeg har overloadet operatoren << med en funktion der returnerer en
char-pointer. Her vil klassen ikke selv kunne frigøre hukommelsen, hvis man
nu skriver cout << a; - hvor a er en MyClass-klasse. Eller er det bare mig
der er 'blind'?

> Det er sikkert rigtigt (= jeg er ikke sikker på det sker i alle
> tilfælde), når det bliver sagt at Windows/Linux frigiver pladsen igen,
> men det er så absolut ikke den pæne måde at gøre tingene på.
>
> Hvis du eksempel vis kalder din funktion 100 gange i et programforløb,
> vil programmet (inden det afsluttes) have lagt beslag på en mængde
> hukommelse som sikkert ikke skal bruges til noget, og dette vil jo
> ikke blive frigjort før programmet afsluttes.

Selvom det er muligt at hukommelsen bliver frigjort, når et program slutter,
har jeg det også bedst med selv at frigøre rammen - så man kan se at der
bliver bliver noget hukommelse allokeret og der bliver det frigjort ... så
er man ikke i tvivl om det bliver frigjort :)

> Det er nu en generel regl at man frigiver allokeret hukommelse igen,
> lige så snart man ikke skal bruge det mere, så andre processer kan få
> nytte af det.
>
> /Thomas

Mvh. Bjarke



Kent Friis (26-05-2002)
Kommentar
Fra : Kent Friis


Dato : 26-05-02 21:13

Den Sun, 26 May 2002 21:16:13 +0200 skrev Bjarke Walling Petersen:
>Thomas Lykkeberg skrev:
>[snip]
>> Hvis du arbejder i C++ kan du jo lave en klasse i stedet for en
>> funktion. Her kunne kontruktøren så allokerer pladsen til strengen med
>> new og destruktøren kunne så frigive pladsen igen med delete, når
>> objektet bliver "nedbrudt".
>
>Ja, det ved jeg ... jeg benytter dem ofte.
>Selvom det var af ren nysgerrighed jeg stilte spørgsmålet, er jeg kommet på
>et evt. problem angående frigørelse af hukommelse (det er ikke noget problem
>jeg selv har lige nu!). F.eks. lad os sige jeg har en klasse MyClass og at
>jeg har overloadet operatoren << med en funktion der returnerer en
>char-pointer. Her vil klassen ikke selv kunne frigøre hukommelsen, hvis man
>nu skriver cout << a; - hvor a er en MyClass-klasse. Eller er det bare mig
>der er 'blind'?

hvis MyClass også selv har en pointer, kan den frigive den når
destructoren kaldes, og naturligvis inden den allokerer et nyt
hukommelsesområde.

Mvh
Kent
--
Hvis man ikke kan lide klassisk musik, er det sandsynligvis fordi
lydkvaliteten er for dårlig. Klassisk musik kræver et godt anlæg.

Bjarke Walling Peter~ (26-05-2002)
Kommentar
Fra : Bjarke Walling Peter~


Dato : 26-05-02 23:53

Kent Friis skrev:
> hvis MyClass også selv har en pointer, kan den frigive den når
> destructoren kaldes, og naturligvis inden den allokerer et nyt
> hukommelsesområde.

Det er rigtigt! Så skal man blot ikke selv prøve at frigive den, hvor den
bliver brugt

Mvh. Bjarke



Bertel Lund Hansen (26-05-2002)
Kommentar
Fra : Bertel Lund Hansen


Dato : 26-05-02 21:32

Bjarke Walling Petersen skrev:

>Selvom det var af ren nysgerrighed jeg stilte spørgsmålet, er jeg kommet på
>et evt. problem angående frigørelse af hukommelse (det er ikke noget problem
>jeg selv har lige nu!).

Det er rigtigt at man kan miste forbindelsen til noget allokeret
hukommelse. Man skal selv sørge for at deallokere inden man
ændrer en pointer, og til en klasse som dynamisk allokerer
hukommelse kan man blive nødt til selv at skrive dens destruktør
fordi det ellers kun er den egne variable der nedlægges.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Mogens Hansen (27-05-2002)
Kommentar
Fra : Mogens Hansen


Dato : 27-05-02 21:33


"Bjarke Walling Petersen" <bwp@bwp.dk> wrote

[snip]
> char *str;
> str = new char(x+1);

Jeg tror ikke at koden gør det som du tror.
Du allokerer _en_ char på heapen, som bliver initialiseret med værdien x.
Jeg antager at du ønskede at allokere et array af char, med en længde på
x+1.
Idet jeg foretrækker at erklære og initialisere variable samtidig, hvis det
er muligt, bliver det til
char* str = new char[x+1];

> // Selvfølgelig burde man også checke at x!=0 og
> str ikke bliver sat til NULL

Nej, man må gerne skrive "new char[0]", og det giver _ikke_ 0 tilbage. Den
situation vil du dog ikke komme i, idet du altid allokerer "x+1". Man må
naturligvis ikke tilgå hukommelse ud over hvad man har allokeret.

Nej, man behøves ikke at checke om str bliver sat til 0 - det gør den
_ikke_.
Såfremt new ikke kan allokere den ønskede hukommelse, bliver der smidt en
exception.


[snip]
> str[0] = '<';
> str[x-1] = '>';
> str[x] = '\0';
> return str;

Her skal du naturligvis tage hensyn til størrelsen på x, sådan som du
egentlig også siger man burde.
Her skriver du i ikke allokeret hukommelse, fordi det ikke er et array du
har allokeret, som nævnt ovenfor.
Jeg kan varmt anbefale at bruge værktøjer, såsom CodeGuard som er en del af
Borland C++Builder Professional og Enterprise, til at hjælpe med at finde
den slags fejl. Der findes flere andre værktøjer, der har samme formål.

> } // Tag jer ikke af at funktionen egentlig ikke kan bruges til noget
> fornuftigt!
>
> int main(int argc, char *argv[])
> {
> cout << funktion(10) << endl;
> return 0; // Bliver strengen jeg oprettede i 'funktion' nu frigjort
fra
> rammen?

Ikke nødvendigvis.
Selv hvis man befinder sig i omgivelser, der frigiver hukommelse efter
programmet er termineret, mener jeg det er en dårlig vane at basere sig på
det.
Det gør det langt sværere at anvende værktøjer, der hjælper med at finde
leaks.
Tænk også på det som resourcer generelt: file-handles, database
transaktioner, netværks forbindelser. Database resourcer er specielt
interessante, fordi man kan have allokeret resourcer i en anden proces.

Det er ikke vanskelligt at undgå.
I dit eksempel kunne man have brugt klassen std::string:

std::string funktion(unsigned x)
{
std::string result(x, '-');
if(x > 0)
result[0] = '<';
if(x > 2)
result[x-1] = '>';
return result;
}

int main(void)
{
std::cout << funktion(10) << std::endl; // No problem
}

Det er enklere, klarere, sikrere og giver _ingen_ _mulighed_ for
memory-leak.
Det behøver end ikke at være langsommere.

Venlig hilsen

Mogens Hansen



Bjarke Walling Peter~ (28-05-2002)
Kommentar
Fra : Bjarke Walling Peter~


Dato : 28-05-02 22:31

Mogens Hansen skrev:
> Jeg tror ikke at koden gør det som du tror.
> Du allokerer _en_ char på heapen, som bliver initialiseret med værdien x.
> Jeg antager at du ønskede at allokere et array af char, med en længde på
> x+1.
> Idet jeg foretrækker at erklære og initialisere variable samtidig, hvis
det
> er muligt, bliver det til
> char* str = new char[x+1];

Ja, det er rigtigt. Jeg var åbenbart lidt for hurtig til at skrive beskeden.
Ved du hvad 'new char(x+1)' allokerer? - for det virker tilsyneladende også
(jeg tester altid hurtigt mine programmer, før jeg sender koden) - selvom
det jo er char[x+1] der er det rigtige.

> > // Selvfølgelig burde man også checke at x!=0 og
> > str ikke bliver sat til NULL
>
> Nej, man må gerne skrive "new char[0]", og det giver _ikke_ 0 tilbage. Den
> situation vil du dog ikke komme i, idet du altid allokerer "x+1". Man må
> naturligvis ikke tilgå hukommelse ud over hvad man har allokeret.
>
> Nej, man behøves ikke at checke om str bliver sat til 0 - det gør den
> _ikke_.
> Såfremt new ikke kan allokere den ønskede hukommelse, bliver der smidt en
> exception.

"If there is insufficient memory for the allocation request, by default
operator new returns NULL. You can change this default behavior by writing a
custom exception-handling routine and calling the _set_new_handler run-time
library function with your function name as its argument. For more details
on this recovery scheme, see The operator new Function." -- under 'new
Operator' i MSDN Library.

Hvis jeg ikke, som der står, har skrevet min egen fejlroutine og kaldt
_set_new_handler, vil new returnere NULL når der ikke er nok plads - eller
har jeg fejlfortolket det?
Måske du evt. kunne fortæller hvordan en sådan routine laves, så jeg kan
bruge det i stedet? Det er jo mere 'højniveau'sk'.

> [snip]
> > str[0] = '<';
> > str[x-1] = '>';
> > str[x] = '\0';
> > return str;
>
> Her skal du naturligvis tage hensyn til størrelsen på x, sådan som du
> egentlig også siger man burde.

Det var rent faktisk også i den henseende at jeg skrev det.

> Her skriver du i ikke allokeret hukommelse, fordi det ikke er et array du
> har allokeret, som nævnt ovenfor.
> Jeg kan varmt anbefale at bruge værktøjer, såsom CodeGuard som er en del
af
> Borland C++Builder Professional og Enterprise, til at hjælpe med at finde
> den slags fejl. Der findes flere andre værktøjer, der har samme formål.

Hvad med i Microsoft Visual C++ 6.0?

> > } // Tag jer ikke af at funktionen egentlig ikke kan bruges til noget
> > fornuftigt!
> >
> > int main(int argc, char *argv[])
> > {
> > cout << funktion(10) << endl;
> > return 0; // Bliver strengen jeg oprettede i 'funktion' nu frigjort
> fra
> > rammen?
>
> Ikke nødvendigvis.
> Selv hvis man befinder sig i omgivelser, der frigiver hukommelse efter
> programmet er termineret, mener jeg det er en dårlig vane at basere sig på
> det.

Jeg vil selvfølgelig selv frigøre rammen - udover at det medfører
midlertidig pladsspild, kan det også være forvirrende ikke at kunne se hvor
den bliver frigjort.

> Det gør det langt sværere at anvende værktøjer, der hjælper med at finde
> leaks.
> Tænk også på det som resourcer generelt: file-handles, database
> transaktioner, netværks forbindelser. Database resourcer er specielt
> interessante, fordi man kan have allokeret resourcer i en anden proces.
>
> Det er ikke vanskelligt at undgå.
> I dit eksempel kunne man have brugt klassen std::string:
>
> std::string funktion(unsigned x)
> {
> std::string result(x, '-');
> if(x > 0)
> result[0] = '<';
> if(x > 2)
> result[x-1] = '>';
> return result;
> }
>
> int main(void)
> {
> std::cout << funktion(10) << std::endl; // No problem
> }
>
> Det er enklere, klarere, sikrere og giver _ingen_ _mulighed_ for
> memory-leak.
> Det behøver end ikke at være langsommere.

Så ved jeg det - det jeg ikke vidste i forvejen. Tak for svaret.

Mvh. Bjarke



Mogens Hansen (29-05-2002)
Kommentar
Fra : Mogens Hansen


Dato : 29-05-02 06:21


"Bjarke Walling Petersen" <bwp@bwp.dk> wrote
> Mogens Hansen skrev:

[snip]
> Ja, det er rigtigt. Jeg var åbenbart lidt for hurtig til at skrive
beskeden.
> Ved du hvad 'new char(x+1)' allokerer? - for det virker tilsyneladende
også
> (jeg tester altid hurtigt mine programmer, før jeg sender koden) - selvom
> det jo er char[x+1] der er det rigtige.
>

Nej, det virker ikke - det ser bare sådan ud.
Det er undefined behaviour - hvad som helst kan ske. Herunder at det ser ud
som om det virker.
Prøv at kalde "funktion" med et stort tal. På et eller andet tidspunkt får
du en general protection fault, fordi du skriver i ikke allokeret
hukommelse.

[snip]
>
> "If there is insufficient memory for the allocation request, by default
> operator new returns NULL. You can change this default behavior by writing
a
> custom exception-handling routine and calling the _set_new_handler
run-time
> library function with your function name as its argument. For more details
> on this recovery scheme, see The operator new Function." -- under 'new
> Operator' i MSDN Library.
>

Jeg talte om C++ (sådan som det er defineret i C++ Standarden ISO/IEC
14882:1998) - ikke en eller anden ældgammel tilnærmelse. For ca. 10 år siden
var det sådan, men ikke de sidste 6-8 år.
Det er fordi du bruger Visual C++ V6.0, som ikke overholder C++ Standarden
på dette punkt.
Hvis du vil bruge Microsofts compiler, vil jeg anbefale at du upgradere til
Visual C++ V7.0 (.NET), som overholder C++ Standarden langt bedre. F.eks.
overholder den standarden på dette punkt.
MSDN er en god kilde til at lære MS-Windows programmering, men ikke en god
kilde til lære C++ programmering.

> Hvis jeg ikke, som der står, har skrevet min egen fejlroutine og kaldt
> _set_new_handler, vil new returnere NULL når der ikke er nok plads - eller
> har jeg fejlfortolket det?

Nej, det har du forstået rigtigt.
Det er blot gammel information, som ikke engang var gældende for C++ da
Visual C++ V6.0 blev frigivet.

> Måske du evt. kunne fortæller hvordan en sådan routine laves, så jeg kan
> bruge det i stedet? Det er jo mere 'højniveau'sk'.
>

Jeg forstår ikke spørgsmålet.
Hvilken rutine tænker du på ?
Hvis det er opførslen fra "operator new", så er løsningen at få fat på en
mere moderne compiler.

[snip]
> > Jeg kan varmt anbefale at bruge værktøjer, såsom CodeGuard som er en del
> af
> > Borland C++Builder Professional og Enterprise, til at hjælpe med at
finde
> > den slags fejl. Der findes flere andre værktøjer, der har samme formål.
>
> Hvad med i Microsoft Visual C++ 6.0?
>

NuMega BoundsChecker (www.numega.com) og Rational Purfiy (www.rational.com).
Begge er gode, men det er min erfaring at de ikke er helt så gode som
CodeGuard til at finde fejl i C++ programmer.
En anden mulighed er at download en trial udgave af Borland C++Builder V6.0
Enterprise (www.borland.com) og prøve CodeGuard.

[snip]
> Så ved jeg det - det jeg ikke vidste i forvejen. Tak for svaret.

Du er velkommen, men tænk over hvad du har set:
* Foretræk højniveau konstruktioner (f.eks. "std::string") frem for
lavniveau konstruktioner ("operator new" etc.).
Det er enklere og sikrere
* Brug værktøjer, der kan afsløre undefined behaviour
* Brug en moderne C++ compiler
* Få fat på en god C++ reference, f.eks.
The C++ Programming Language, Special Edition
Bjarne Stroustrup
ISBN 0-201-70073-5

Venlig hilsen

Mogens Hansen



Bjarke Dahl Ebert (29-05-2002)
Kommentar
Fra : Bjarke Dahl Ebert


Dato : 29-05-02 13:57

"Bjarke Walling Petersen" <bwp@bwp.dk> wrote in message
news:3cf3f72b$0$97302$edfadb0f@dspool01.news.tele.dk...
> Mogens Hansen skrev:
> > char* str = new char[x+1];
>
> Ja, det er rigtigt. Jeg var åbenbart lidt for hurtig til at skrive
beskeden.
> Ved du hvad 'new char(x+1)' allokerer? - for det virker tilsyneladende
også

Hehe - endnu en "Gæt hvad dette C++ kode gør"

Generelt vil "new Foo(...)" allokere et Foo-objekt på heapen, initialiseret
af constructor'en med argumenter "...".
Nu er Foo så bare en char. Så du allokerer en enkelt char, initialiseret til
char-værdien x+1. (Dvs. int-værdien x+1 konverteret til en char).


Mvh. Bjarke





Desilva (28-05-2002)
Kommentar
Fra : Desilva


Dato : 28-05-02 11:26

> Det kan godt være jeg er en smule 'low level', men hvis man nu absolut
_vil_
> have en funktion der returnerer en pointer til en null-terminated string
> (altså char *) - bliver pladsen som strengen optager i rammen frigjort når
> programmet slutter eller skal man lave nogle fiksfakserier for at dette
> bliver gjort - i så fald hvilke?

Som andre svarer så bliver det frigjort når programmet slutter, men du skal
bemærke at det jo først er ved afslutning af pladsen frigøres, så gentagende
kald til din funktion vil allokere mere og mere plads som bare ligger ubrugt
hen.. og tager resourcer.
Det kan evt fikses ved at lave en static char som initialiseres som new



Søg
Reklame
Statistik
Spørgsmål : 177496
Tips : 31968
Nyheder : 719565
Indlæg : 6408491
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste