/ 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
sizeof(array)
Fra : Preben


Dato : 15-06-04 10:46

Hej alle,

burde sizeof() ikke returnere en længde af et array.
Hvis jeg anvender sizeof() på et char-array får jeg returneret 4 uanset
størrelsen.

det jeg gør er således:


strcpy (char out[], char in[])
{
int i;

while (i < sizeof(out)) {
if (i < sizeof(in)) {
out[i] = in[i];
} else {
out[i] = '\0';
}

i++;
}
}

grunden til jeg vil lave en anden strcpy funktion er at hvis standard
funktionen anvendes vil der ved anvendelsen af out[] mindre end in[]
ikke tjekkes for overflow hvilket er irriterende.


Mvh / Preben Holm

 
 
Bertel Lund Hansen (15-06-2004)
Kommentar
Fra : Bertel Lund Hansen


Dato : 15-06-04 12:16

Preben skrev:

>burde sizeof() ikke returnere en længde af et array.

strlen beregner længden af et array af char.

>det jeg gør er således:

>strcpy (char out[], char in[])

Det kan gøres enklere med pointere:

strcpy (char out[], char in[]) {
while (*out && *in) *(out++)=*(in++);
*out=0;
}

While-betingelsen sikrer at operationen stopper hvis én af
pointerne udpeger en nulværdi. Derfor bestemmer den korteste
streng hvor meget der kopieres. Da den netop går i stå før der
kopieres en nulværdi, skal den sættes i hånden bagefter. Hvis out
er mindst, rammer det 'nye' nul oveni det gamle og gør altså
ingen skade.

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

Mogens Hansen (15-06-2004)
Kommentar
Fra : Mogens Hansen


Dato : 15-06-04 16:14

"Bertel Lund Hansen" <nospamius@lundhansen.dk> wrote:

> Preben skrev:
>
> >burde sizeof() ikke returnere en længde af et array.
>
> strlen beregner længden af et array af char.

Nej.

For det første vil det kræve at char arrayet så benyttes til at indeholde en
nul-termineret streng - hvilket ikke nødvendigvis er tilfældet.
For det andet vil det kræve at den nul-terminerede streng _netop_ fylder
hele arrayet - hvilket ofte ikke er tilfældet.

strlen fortæller hvor langt der er til første '\0'.

Venlig hilsen

Mogens Hansen



Ivan Johansen (15-06-2004)
Kommentar
Fra : Ivan Johansen


Dato : 15-06-04 11:25

Preben wrote:
> burde sizeof() ikke returnere en længde af et array.

Jo, det gør den også.

> Hvis jeg anvender sizeof() på et char-array får jeg returneret 4 uanset
> størrelsen.
>
> det jeg gør er således:
>
> strcpy (char out[], char in[])

Dette er ikke et array, selvom det ligner, men en pointer. Det er bare
en anden måde at skrive:
strcpy(char *out, char *in)

Ivan Johansen

Preben (15-06-2004)
Kommentar
Fra : Preben


Dato : 15-06-04 12:22

>> burde sizeof() ikke returnere en længde af et array.
>
>
> Jo, det gør den også.
>
>> Hvis jeg anvender sizeof() på et char-array får jeg returneret 4
>> uanset størrelsen.
>>
>> det jeg gør er således:
>>
>> strcpy (char out[], char in[])
>
>
> Dette er ikke et array, selvom det ligner, men en pointer. Det er bare
> en anden måde at skrive:
> strcpy(char *out, char *in)

hmm
altså

char out[10] er et array af længde 10
out udgør pointeren til array'et - right?
out[noget] giver out[noget]'s værdi - right?
out[] giver værdien af det som out-pointeren peger på?


men hvordan virker sizeof() så?
Hvad skal sizeof kaldes med af parameter så? ikke pointeren til array'et
eller hvad?


Mvh / Preben

Jesper Larsen (15-06-2004)
Kommentar
Fra : Jesper Larsen


Dato : 15-06-04 12:35

Preben wrote:
[Snip]

>
> char out[10] er et array af længde 10
> out udgør pointeren til array'et - right?
> out[noget] giver out[noget]'s værdi - right?

Jep

> out[] giver værdien af det som out-pointeren peger på?

"out[]" giver ikke noget. Det bruges bare til at angive at en funktion
tager et array som parameter. Hvis du vil have det out peger på, dvs.
det første element i arrayet kan du bruge out[0] eller *out.

>
>
> men hvordan virker sizeof() så?
> Hvad skal sizeof kaldes med af parameter så? ikke pointeren til array'et
> eller hvad?

Jeg tror, at dit problem er, at du ikke kan bruge sizeof til at bestemme
længden af arrayet på runtime. Såvidt jeg ved er sizeof en makro, så
størrelsen af parametren bliver sat ind på compile-tidspunktet. Hvis man
ser på funktionen

void func(char in[], char out[])

er der jo ikke nogen måde at bestemme længden af de to arrays på. Det
afhænger af koden hvorfra funktionen kaldes. En løsning kunne være at
bruge null-terminering eller overføre længden af arrayet som parameter.


Håber det hjalp dig lidt, det kunne vist forklares bedre


--
Venligst
Jesper Larsen

Byrial Jensen (15-06-2004)
Kommentar
Fra : Byrial Jensen


Dato : 15-06-04 18:15

Jesper Larsen wrote:

> Såvidt jeg ved er sizeof en makro, så
> størrelsen af parametren bliver sat ind på compile-tidspunktet.

sizeof er en operator. Ofte, men ikke altid, kan oversætteren udregne
værdien på oversættelsestidspunktet, men det er i princippet ikke
forskelligt fra at den normalt også kan beregn værdien af udtrykket 2+2
på oversættelsestidspunktet.

Bertel Brander (15-06-2004)
Kommentar
Fra : Bertel Brander


Dato : 15-06-04 19:00

Byrial Jensen wrote:

> Jesper Larsen wrote:
>
>> Såvidt jeg ved er sizeof en makro, så størrelsen af parametren bliver
>> sat ind på compile-tidspunktet.
>
>
> sizeof er en operator. Ofte, men ikke altid, kan oversætteren udregne
> værdien på oversættelsestidspunktet, men det er i princippet ikke
> forskelligt fra at den normalt også kan beregn værdien af udtrykket 2+2
> på oversættelsestidspunktet.

Preprocessoren kan regne 2+2, men kender ikke sizeof().

/b

Byrial Jensen (15-06-2004)
Kommentar
Fra : Byrial Jensen


Dato : 15-06-04 22:17

Bertel Brander wrote:
> Byrial Jensen wrote:
>>
>> sizeof er en operator. Ofte, men ikke altid, kan oversætteren udregne
>> værdien på oversættelsestidspunktet, men det er i princippet ikke
>> forskelligt fra at den normalt også kan beregn værdien af udtrykket
>> 2+2 på oversættelsestidspunktet.
>
> Preprocessoren kan regne 2+2, men kender ikke sizeof().

Det er rigtigt. Der er også mange andre ting man ikke gøre i
preprocessoren, men hvad er pointen med det?

Og her er et program med en sizeof operator hvor resultatet ikke kendes
på oversættelsestidspunktet:

#include <stdio.h>
int main (int argc, char *argv[])
{
char array [argc];
printf ("sizeof array = %zu\n", sizeof array);
return 0;
}

Igor V. Rafienko (15-06-2004)
Kommentar
Fra : Igor V. Rafienko


Dato : 15-06-04 19:10

[ Jesper Larsen ]

[ ... ]

> > strcpy (char out[], char in[])
:
> > char out[10] er et array af længde 10
> > out udgør pointeren til array'et - right?
> > out[noget] giver out[noget]'s værdi - right?
>
> Jep


Hvis man snakker om det opprinnelige eksemepelet, så er "Jep"en
feilplassert.

out utgjør *ikke* en peker til en array. out er en peker til det
første elementet i en array. Det er en *vesentlig* forskjell mellom
disse to.

<URL: http://web.torek.net/torek/c/pa.html>

(Og boken til Peter van der Linden for en meget detaljert gjennomgang).

[ ... ]





ivr
--
<html><form><input type crash></form></html>

Jesper Larsen (15-06-2004)
Kommentar
Fra : Jesper Larsen


Dato : 15-06-04 20:17

Igor V. Rafienko wrote:
> [ Jesper Larsen ]
>
> [ ... ]
>
>> > strcpy (char out[], char in[])
> :
>> > char out[10] er et array af længde 10
>> > out udgør pointeren til array'et - right?
>> > out[noget] giver out[noget]'s værdi - right?
>>
>> Jep
>
>
> Hvis man snakker om det opprinnelige eksemepelet, så er "Jep"en
> feilplassert.
>
> out utgjør *ikke* en peker til en array. out er en peker til det
> første elementet i en array. Det er en *vesentlig* forskjell mellom
> disse to.
>
> <URL: http://web.torek.net/torek/c/pa.html>

Ups, det vil jeg give dig ret i.

En pointer til arrayet vil se således ud:

   char *(out[10]) ptr;

ikke?


--
Venligst
Jesper Larsen

Igor V. Rafienko (15-06-2004)
Kommentar
Fra : Igor V. Rafienko


Dato : 15-06-04 23:53

[ Jesper Larsen ]

[ ... ]

> En pointer til arrayet vil se således ud:
>
>    char *(out[10]) ptr;
>
> ikke?


cdecl> declare out as pointer to array 10 of int
int (*out)[10]
cdecl>





ivr
--
<html><form><input type crash></form></html>

Mogens Hansen (15-06-2004)
Kommentar
Fra : Mogens Hansen


Dato : 15-06-04 16:15

"Ivan Johansen" <NG5@Padowan.remove.dk> wrote

> Preben wrote:
> > burde sizeof() ikke returnere en længde af et array.
>
> Jo, det gør den også.

Ikke længden forstået som hvor mange elementer arrayet har, men længden
forstået som hvor mange bytes fylder det.

Antallet af elementer bestemmes ved sizeof(array)/sizeof(array[0]) - selvom
det heller ikke hjælper Preben

Venlig hilsen

Mogens Hansen



René Larsen (15-06-2004)
Kommentar
Fra : René Larsen


Dato : 15-06-04 13:01

In article <40cec3eb$0$23872$14726298@news.sunsite.dk>, Preben wrote:
> burde sizeof() ikke returnere en længde af et array.

Det gør den også.

> Hvis jeg anvender sizeof() på et char-array får jeg returneret 4 uanset
> størrelsen.

Når først en function er kaldt, er alle oplysninger om længder af arrays
glemt/smidt væk.

Når man skal overføre strenge til en funktion kan man skrive det på to
måder:

void testarr(char s[]);
void testptr(char *s);

Forskellen er så lille, at Kernigan & Ritchie's C bibel SVJH bruger et
enkelt afsnit på forskellen og ender med at sige, at den kun kommer til at
betyde noget for meget få programmører, så man kan lige så godt glemme den
igen ;)

> grunden til jeg vil lave en anden strcpy funktion er at hvis standard
> funktionen anvendes vil der ved anvendelsen af out[] mindre end in[]
> ikke tjekkes for overflow hvilket er irriterende.

I C er det programmørens pligt at checke, om der er plads *før* strcpy()
kaldes.

Her er et testprogram der viser problemet:

#include <stdio.h>
void test(char out[], char in[]) {
printf("sizeof(in) = %d, sizeof(out) = %d\n",
sizeof(in), sizeof(out));
}
int main(void) {
char in[10];
char out[5];
printf("sizeof(in) = %d, sizeof(out) = %d\n",
sizeof(in), sizeof(out));
test(out, in);
return 0;
}

Og her er uddata:
sizeof(in) = 10, sizeof(out) = 5
sizeof(in) = 4, sizeof(out) = 4

En mulighed er at bruge strncpy(). Så kan du sætte en max længde på det,
der skal kopieres. Hvis du laver en #define sådan her:

#define strcpy(out, in) strncpy(out, in, sizeof(out));

undgår du at lave dit program alt for meget om.

MVH, René



Bertel Lund Hansen (15-06-2004)
Kommentar
Fra : Bertel Lund Hansen


Dato : 15-06-04 14:36

René Larsen skrev:

>der skal kopieres. Hvis du laver en #define sådan her:

> #define strcpy(out, in) strncpy(out, in, sizeof(out));

>undgår du at lave dit program alt for meget om.

strncpy() kopierer ikke altid 0-byten med, og det vil drille ved
din metode.

int main() {
char source[]="Kilde", target[]="MålMålMål";
strncpy(target,source,strlen(source));
printf("Længde: %d %s\n",strlen(target),target);

return 0;
}

Her vil resultatet blive "Længde: 9 KildelMål".

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

Troels Thomsen (15-06-2004)
Kommentar
Fra : Troels Thomsen


Dato : 15-06-04 16:18


> #define strcpy(out, in) strncpy(out, in, sizeof(out));
>
> undgår du at lave dit program alt for meget om.
>

Ja, men det kræver at alle strengene er defineret som

char str1[MYLENGTH] ;

og ikke således:

char* str2 = new char[MYLENGTH];

Ellers får man lænden 4 igen.



Mogens Hansen (15-06-2004)
Kommentar
Fra : Mogens Hansen


Dato : 15-06-04 16:33


"René Larsen" <rene.larsen@spamfilter.dk> wrote: in message
news:VA.00000020.01068f60@spamfilter.dk...
> In article <40cec3eb$0$23872$14726298@news.sunsite.dk>, Preben wrote:
> > burde sizeof() ikke returnere en længde af et array.
>
> Det gør den også.

Nej.
sizeof udtrykker hvor meget hukommelse parameteren fylder i bytes.

[8<8<8<]

> En mulighed er at bruge strncpy(). Så kan du sætte en max længde på det,
> der skal kopieres. Hvis du laver en #define sådan her:
>
> #define strcpy(out, in) strncpy(out, in, sizeof(out));

Det vil langtfra virke

Venlig hilsen

Mogens Hansen



Preben (15-06-2004)
Kommentar
Fra : Preben


Dato : 15-06-04 16:49

>>>burde sizeof() ikke returnere en længde af et array.
>>
>>Det gør den også.
>
>
> Nej.
> sizeof udtrykker hvor meget hukommelse parameteren fylder i bytes.
>
> [8<8<8<]
>
>
>>En mulighed er at bruge strncpy(). Så kan du sætte en max længde på det,
>>der skal kopieres. Hvis du laver en #define sådan her:
>>
>> #define strcpy(out, in) strncpy(out, in, sizeof(out));
>
>
> Det vil langtfra virke


Okai, inden jeg bliver helt forvirret:

strlen() returnerer antallet af bytes (chars) indtil første '\0' (er det
med eller uden '\0'?

sizeof() returnerer størrelsen af array'et, men ikke hvis array'et
overføres som f.eks. paramter til en anden funktion!

Korrekt?


Mvh / Preben Holm

Mogens Hansen (15-06-2004)
Kommentar
Fra : Mogens Hansen


Dato : 15-06-04 16:59


"Preben" <64bitNOnoNOSPAM@mailme.dk> wrote:

[8<8<8<]
> strlen() returnerer antallet af bytes (chars) indtil første '\0' (er det
> med eller uden '\0'?

Det terminerende '\0' er ikke talt med.

>
> sizeof() returnerer størrelsen af array'et,

målt i bytes - ikke antal elementer

> men ikke hvis array'et
> overføres som f.eks. paramter til en anden funktion!
>
> Korrekt?


Nej.

Det kommer an på hvordan arrayet er overført til funktionen.

Bemærk at et array kan implicit konverteres til en pointer.


Venlig hilsen

Mogens Hansen



Preben (15-06-2004)
Kommentar
Fra : Preben


Dato : 15-06-04 17:43

>>strlen() returnerer antallet af bytes (chars) indtil første '\0' (er det
>>med eller uden '\0'?
>
>
> Det terminerende '\0' er ikke talt med.
>
>
>>sizeof() returnerer størrelsen af array'et,
>
>
> målt i bytes - ikke antal elementer
>
>
>>men ikke hvis array'et
>>overføres som f.eks. paramter til en anden funktion!
>>
>>Korrekt?
>
>
>
> Nej.
>
> Det kommer an på hvordan arrayet er overført til funktionen.
>
> Bemærk at et array kan implicit konverteres til en pointer.
>

Hvordan gøres det så?

Mogens Hansen (15-06-2004)
Kommentar
Fra : Mogens Hansen


Dato : 15-06-04 18:13


"Preben" <64bitNOnoNOSPAM@mailme.dk> wrote:

[8<8<8<]
> > Det kommer an på hvordan arrayet er overført til funktionen.
> >
> > Bemærk at et array kan implicit konverteres til en pointer.
> >
>
> Hvordan gøres det så?

<C++ kode>
#include <iostream>

using namespace std;

typedef double ten_doubles[10];

void foo(ten_doubles& arr_d, char arr_c[10])
{
cout << "sizeof(arr_d):" << sizeof(arr_d) << endl;
cout << "sizeof(arr_c):" << sizeof(arr_c) << endl;
}

int main()
{
double arr_d[10];
char arr_c[10];

foo(arr_d, arr_c);
}
</C++ kode>


Venlig hilsen

Mogens Hansen



Lasse Westh-Nielsen (15-06-2004)
Kommentar
Fra : Lasse Westh-Nielsen


Dato : 15-06-04 17:33

"Preben" <64bitNOnoNOSPAM@mailme.dk> wrote in message
news:40cf1927$0$23875$14726298@news.sunsite.dk...

> sizeof() returnerer størrelsen af array'et, men ikke hvis array'et
> overføres som f.eks. paramter til en anden funktion!

sizeof returnerer størrelsen (i bytes) af det du giver den, altså den mængde
hukommelse argumentet fylder:

- hvis du giver den et array, så returnerer den størrelsen af arrayet.
altså længdne af arrayet gange størrelsen af typen i arrayet
- hvis du giver den en pointer så returnerer den størrelsen af pointeren,
altså størrelsen på en adresse - denne er uafhængig af typen (er den
egentlig ikke forskellig på forskellige arkitekturer?)
- hvis du giver den en type, så returnerer den størrelsen af typen, altså
den mængde hukommelse som eet element fylder

Prøv eventuelt følgende (kommentarerne er det resultat jeg får på min 32-bit
PC):

#include <stdio.h>

void main()
{
char chars[100];
int ints[200];
char* charpointer = &chars;
int* intpointer = &ints;

printf("%d\n", sizeof chars); /* 100 */
printf("%d\n", sizeof ints); /* 800 */
printf("%d\n", sizeof charpointer); /* 4 */
printf("%d\n", sizeof intpointer); /* 4 */
printf("%d\n", sizeof(char)); /* 1 */
printf("%d\n", sizeof(int)); /* 4 */
}


Med venlig hilsen

- Lasse


--
Lasse Westh-Nielsen
lasse@daimi.au.dk




Byrial Jensen (15-06-2004)
Kommentar
Fra : Byrial Jensen


Dato : 15-06-04 21:23

Lasse Westh-Nielsen wrote:

> - hvis du giver den en pointer så returnerer den størrelsen af pointeren,
> altså størrelsen på en adresse - denne er uafhængig af typen

Størrelsen af pointer er afhængig af typen. Pointere til funktioner har
ikke nødvendigvis samme størrelse som pointere til objekter.

> (er den
> egentlig ikke forskellig på forskellige arkitekturer?)

Jo.

> #include <stdio.h>
>
> void main()

main() returnerer int! Der kan ikke afviges fra dette.

Søg
Reklame
Statistik
Spørgsmål : 177459
Tips : 31964
Nyheder : 719565
Indlæg : 6408183
Brugere : 218881

Månedens bedste
Årets bedste
Sidste års bedste