Forum: PC-Programmierung Char Array ist leer übetragen obwohl malloc


von Halgn H. (Gast)


Lesenswert?

Hi,

ich möchte gerne eine Char Array übetragen aber es geht oder zu teil.
1
unsigned char *Entity;
2
3
void Entity_Init()
4
{
5
    int i;
6
7
    /* Speicher reseviren */
8
    Entity = (unsigned char*)malloc(Entity_Size*Entity_Max+1);
9
10
    for(i = 0; i < Entity_Size*Entity_Max; i++)
11
        Entity[i] = 0;
12
}

Es klappt auch und ich kann damit arbeiten aber sobald ich strlen() 
nützte kommen falsche werte raus und ich kann es nicht über das 
netztwerk übetragen(nur bis 0 auftaucht) :/

So ruf ich es auf:
1
    Network_SendMsg(Network_Clients[i].Socket, &Entity);

Hier nochmal das mit strlen:
1
/* Nachricht senden */
2
int *Network_SendMsg(TCPsocket sock, char *buf)
3
{
4
  Uint32 len,result;
5
6
  if(!buf || !strlen(buf))
7
    return(1);
8
9
  /* determine the length of the string */
10
  len=strlen(buf)+1; /* add one for the terminating NULL */
11
12
  /* change endianness to network order */
13
  len=SDL_SwapBE32(len);
14
15
  /* send the length of the string */
16
  result=SDLNet_TCP_Send(sock,&len,sizeof(len));
17
  if(result<sizeof(len)) {
18
    if(SDLNet_GetError() && strlen(SDLNet_GetError())) /* sometimes blank! */
19
      printf("SDLNet_TCP_Send: %s\n", SDLNet_GetError());
20
    return(0);
21
  }
22
23
  /* revert to our local byte order */
24
  len=SDL_SwapBE32(len);
25
26
  /* send the buffer, with the NULL as well */
27
  result=SDLNet_TCP_Send(sock,buf,len);
28
  if(result<len) {
29
    if(SDLNet_GetError() && strlen(SDLNet_GetError())) /* sometimes blank! */
30
      printf("SDLNet_TCP_Send: %s\n", SDLNet_GetError());
31
    return(0);
32
  }
33
34
  /* return the length sent */
35
  return(result);
36
}

Wie kann ich das lösen? Es klappt ja z.B. "Hallo das ist ein test" aber 
warum klappt nicht mit Entity? Sind wirklich die 0 schuld und wie kann 
ich sie beheben? komm echt nicht mehr weiter und suche seit einem tag 
nach antworten

MgG nightalex

: Verschoben durch User
von Halgn H. (Gast)


Lesenswert?

Soory kann es nicht verschieben in PC-Programmierung...

von Karl H. (kbuchegg)


Lesenswert?

Alexander Herberg schrieb:


> Es klappt auch und ich kann damit arbeiten aber sobald ich strlen()
> nützte kommen falsche werte raus und ich kann es nicht über das
> netztwerk übetragen(nur bis 0 auftaucht) :/

Tja.
Du musst dich entscheiden.
Hast du Strings oder hast du keine Strings.
Nur dann , wenn du tatsächlich mit Strings (also Texten) operierst 
kannst du mit strlen arbeiten.
Sind deine Daten aber im weitesten Sinne einfach nur Ansammlungen von 
Bytes, dann liegt es an dir, irgendwelche Längenangaben mitzuführen. C 
an sich tut das nicht. Es tut das auch im Falle von Strings nicht, nur 
gilt halt da die Vereinbarung: Ein String ist dort zu Ende, wo das 
0-Byte auftaucht. Ob da das enthaltende Array zu Ende ist oder nicht, 
interessiert die Stringfunktionen nicht.

von Peter II (Gast)


Lesenswert?

ich versteht nicht was du meinst.

in C ist ein string die länge bis zum ersten 0 byte. Wenn also das erste 
zeichen eine \0 ist liefert strlen 0 zurück. Was erwartest du was da 
zurückkommt?

von Karl H. (kbuchegg)


Lesenswert?

Alexander Herberg schrieb:

> warum klappt nicht mit Entity? Sind wirklich die 0 schuld und wie kann
> ich sie beheben? komm echt nicht mehr weiter und suche seit einem tag
> nach antworten

Mit dem Durcharbeiten eines C-Buches wärst du deutlich schneller 
gewesen. Denn dann wüsstest du, wie Strings in C funktionieren, wie man 
die str... Funktionen einsetzt, wann  man sie einsetzen kann und wann 
nicht.

Aber so rächt sich eben alles irgendwann im Leben. Wer meint, er könne 
eine Programmiersprache ohne vernünftige Unterlagen lernen, zahlt dann 
eben auf lange Sicht Lehrgeld in Form von mehr Zeit, als er zum 
Durcharbeiten eines Lehrbuches benötigt hätte.

Und PS: Da warten auf dich noch viele, viele, viele andere Probleme und 
Problemchen.

von Andreas B. (andreas_b77)


Lesenswert?

Alexander Herberg schrieb:
> unsigned char *Entity;

> So ruf ich es auf:    Network_SendMsg(Network_Clients[i].Socket, &Entity);

> int *Network_SendMsg(TCPsocket sock, char *buf)

Ganz abgesehen von der strlen()-Verwirrung, entweder stimmt das oben 
geschriebene nicht oder der Compiler hat sich schon beschwert. Sowas 
sollte man dann auch nicht ignorieren.

von Halgn H. (Gast)


Lesenswert?

Hallo,

hab nun eine lösung:

Alle Werte um eine 1 erhöhen
1
Entity[(iN * Entity_Size) + Type] = iData+1;
und beim ablesen 1 abziehen
1
(Entity[(iN * Entity_Size) + Type])-1;

das klappt perfekt... aber ein hacken gibt es ja ich kann 255 nicht mehr 
setzten, aber das ist mir egal.

PS: Den Lösungweg hab ich aus einem anderen Forum bekommen.

MfG
nightalex

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Alexander Herberg schrieb:
> PS: Den Lösungweg hab ich aus einem anderen Forum bekommen.

Das ist kein Lösungsweg, das ist Pfusch.

von Karl H. (kbuchegg)


Lesenswert?

So wie ich dein Problem sehe, hast du nicht verstanden, was dein Problem 
ist.

Das hast nicht verstanden, dass es einen tiefen, grundlegenden, 
konzeptionellen Unterschied zwischen ordinären und schnöden Bytefeldern 
und Strings gibt.

Du hast ordinäre und schnöde Bytefelder und keine Strings. Du versuchst 
sie aber wie Strings zu behandlen. Und das klappt eben nicht.
Und solange du dir dessen nicht bewusst bist, und auch nicht verstehst, 
warum deine 'Lösung', wie Rufus so schön sagt, Pfusch ist, solange wirst 
du immer nur ein drittklassiger Programmierer bleiben und von einem 
Problem zum nächsten stolpern. So lange, bis dann irgenwann das ganze 
Kartenhaus in sich zusammenbricht, weil die notdürftig gepfuschten 
Heftpflaster das Haus nicht mehr tragen können.

So lange, bis dann irgendwann ein richtiger Programmierer kommt und die 
Funktion Network_SendMsg zu einer allgemein verwendbaren Funktion 
aufbohrt (und bei der Gelegenheit dann auch gleich noch deinen 
fehlerhaften Returnwert korrigiert) und anstelle 1 Funktion, deren 2 zur 
Verfügung stellt: Eine für ordinäre Bytefelder und eine für Strings.
1
Uint32 Network_SendData(TCPsocket sock, char *buf, Uint32 len)
2
{
3
  Uint32 result;
4
5
  if(!buf)
6
    return(1);
7
8
  /* change endianness to network order */
9
  len=SDL_SwapBE32(len);
10
  ...
11
12
}
13
14
Uint32 Network_SendMsg(TCPsocket sock, char *buf)
15
{
16
  return Network_SendData( sock, buf, strlen(buf) );
17
}

Will er Texte versenden, benutzt er die Funktion Network_SendMsg, will 
er Bytefelder verschicken ist Network_SendData die Funktion der Wahl.


Und genau das ist dann der Grund, warum er weiter seinen Job behält und 
du nicht: Weil er sich nicht mit Pfuschlösungen zufrieden gibt, die 
Nebenbedingungen haben, die dir, ihm oder dem nächsten Programmierer 
irgendwann auf den Kopf fallen; sondern weil er die Probleme ein für 
allemal richtig löst.

von Stefanie B. (sbs)


Lesenswert?

Alexander Herberg schrieb:

>
> das klappt perfekt... aber ein hacken gibt es ja ich kann 255 nicht mehr
> setzten, aber das ist mir egal.
>

Um jetzt wieder die 255 verwenden zu können, kannst du die einfach auch 
noch zusätzlich aufaddieren beim speichern und abziehen wenn du die 
Daten wieder lädst ;)

von Stefanie B. (sbs)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Alexander Herberg schrieb:
>> PS: Den Lösungweg hab ich aus einem anderen Forum bekommen.
>
> Das ist kein Lösungsweg, das ist Pfusch.

Lösungen und Pfuschen sind orthogonal zueinander und schließen sich 
nicht aus.

(Was ist wenn du morgen fertig sein musst?)
Je nachdem auf welche Metrik du optimierst ist diese Lösung sogar 
elegant. ;)

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:
> Rufus Τ. Firefly schrieb:
>> Alexander Herberg schrieb:
>>> PS: Den Lösungweg hab ich aus einem anderen Forum bekommen.
>>
>> Das ist kein Lösungsweg, das ist Pfusch.
>
> Lösungen und Pfuschen sind orthogonal zueinander und schließen sich
> nicht aus.

Doch tun sie.

> (Was ist wenn du morgen fertig sein musst?)

Die (konzeptionell triviale) Änderung dauert 2 Minuten, wenn man es 
richtig macht, sein Handwerk versteht und sich nicht mit halben Lösungen 
zufrieden gibt, die das Potential haben, in der Zukunft zu einem Problem 
zu werden.

(Ganz speziell werden solche Pfusch-Lösungen immer dann zum Problem, 
wenn man das Problem über eine Schnittstelle nach aussen trägt. Denn 
sobald diese Lösung das erste mal beim Kunden ist, wird es extrem schwer 
irgendwann in Zukunft eine saubere Lösung einzuziehen. Dieser 
Pfusch-Hack betrifft ja nicht nur ihn, sondern (weil 
Netzwerk-Verbindung) auch eine Gegenstelle)

> Je nachdem auf welche Metrik du optimierst ist diese Lösung
> sogar elegant.

Sorry. Aber das ist nicht elegant.
Pfusch ist schon das richtige Wort dafür.

von Rolf Magnus (Gast)


Lesenswert?

Stefan B. schrieb:
> Rufus Τ. Firefly schrieb:
>> Alexander Herberg schrieb:
>>> PS: Den Lösungweg hab ich aus einem anderen Forum bekommen.
>>
>> Das ist kein Lösungsweg, das ist Pfusch.
>
> Lösungen und Pfuschen sind orthogonal zueinander und schließen sich
> nicht aus.

Hier wurde nicht verstanden, was das tatsächliche Problem ist und wie 
man es eigentlich richtig macht. Stattdessen wurde ein Workaround 
geschaffen, mit dem's auch irgendwie so einigermaßen geht.
Das ist etwa, wie wenn ich einfach nicht drauf komme, warum die Schraube 
nicht in der Wand hält, wenn ich sie mit einem Hammer reinhaue und als 
generelle "Lösung" dieses Problems fortan alle Schrauben mit 
Zweikomponentenkleber festklebe, nachdem ich sie in die Wand gehauen 
habe.
Geht auch irgendwie, aber elegant ist es nicht gerade.

> Je nachdem auf welche Metrik du optimierst ist diese Lösung sogar
> elegant. ;)

Elegant kann man nur Probleme lösen, die man versteht. Und dieses 
Problem kann man durchaus verstehen, wenn man sich etwas Mühe gibt.

von Karl H. (kbuchegg)


Lesenswert?

Rolf Magnus schrieb:

> Hier wurde nicht verstanden, was das tatsächliche Problem ist und wie
> man es eigentlich richtig macht. Stattdessen wurde ein Workaround
> geschaffen, mit dem's auch irgendwie so einigermaßen geht.

Wobei dieser Hack offenbar an einer Netzwerkschnittstelle sitzt. Und an 
Schnittstellen sind solche Hacks (ohne Not) IMMER eine gaaaaaanz 
schlechte Idee. So was hat ein enormes zukünftiges Frustpotential.

In deinem Beispiel:
Der Schraubenhersteller schreibt vor, dass Schrauben in Wände nur auf 
diese Art und Weise (Hammer + Kleber) montiert werden können. Solange 
man dieses Vorgehen nur in den eigenen 4 Wänden macht gehts ja noch. 
Sobald aber die Schrauben/Hammer/Kleber Sets im Baumarkt verkauft 
werden, wirds problematisch.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.