Grüße, liebe Leser. In diesem Beitrag erfahren Sie, wie Sie die häufigsten Fehler beim Programmieren in C vermeiden.
Falsche Verwendung des Zeilenendezeichens (Nullzeichen '\ 0')
Betrachten Sie den folgenden Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv){
char *str = "Hello \0 world!\n";
int l = strlen(str);
printf("Str: %s\nLength: %d\n", str, l);
}
In diesem Code erhalten wir die folgenden Ergebnisse
Str: Hello
Length: 6
.. "Hello " "world!\n" , , . . :
while((cur_symbol = *++str) != '\0') process_symbol(cur_symbol);
'\0'
strlen 6. . , printf %s str , .
, . ? , , . .. char , , , long int char[], , char * ptr. , 32- , - (, 232 ). char , - .
memcpy :
memcpy(void *dest, const void *source, size_t n);
n- , source, , dest.
, :
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
char *msg = malloc(20);
long int l = 16;
memcpy(msg, &l, 4);
char *c1 = "Hello world!!!\n"; /* length 15 symbols + 1 '\0' symbol */
memcpy(msg + 4, c1, 16);
long int l2 = 0;
memcpy(&l2, msg, 4);
char *c2 = malloc(l2);
memcpy(c2, msg + 4, l2);
printf("Str: %s\nLength: %d\n", c2, l2);
free(msg);
free(c2);
}
. 20 . 4 , 16 . l . memcpy msg. 4 msg . c1, . 16, '\0'
. , memcpy, 5 msg , c1, , , .. l.
, , : l2 c2. C memcpy l2 msg. c2 msg, msg, , l2, .
, printf, l2 c2. ,
Str: Hello world!!!
Length: 16
, . memcpy , char.
memcpy: , , . , , .
, .
:
char *mystr = "This is my string\n";
mystr = mystr + 13;
*mystr = 'u';
Segmentation Fault. , mystr . , .text , . , , mystr , .
malloc, , . - , , . mystr 19 .
free
malloc calloc , .. , , . main, exit , , , , , (, , _exit, , ).
, ? , , , . free , (.. ) :
char *s1 = malloc(255);
process(s1);
free(s1);
, process s1. process , .. 255 , s1. s1, . process :
process(char *s);
, free :
s1 = s1 + 1;
s1, , s1 1 . free, s1 , .
: , , free, .
, , , :
void process_person(struct Person *p){
char name[] = "El Barto\0";
p->name = name;
printf("Person name: %s was initiated\n", p->name);
}
Person, :
struct Person {
char *name;
};
, main, , Person, (name) process_person:
/* in main() body */
struct Person p1;
process_person(&p1);
sleep(2);
printf("Person name is: \"%s\"\n", p1.name);
main, Person , main. process_person, , . , , process_person. name. ( ) name, . , process_person, , 2 . ( sleep). sleep <unistd.h> :
unsigned int sleep(unsigned int seconds);
2 , , , p1. .. , . :
Person name: El Barto was initiated
Person name is: "
, , , - process_person p1.name , \'0'
.
, , , - :
Person name: El Barto was initiated
Person name is: "ElBar2#1"
, :
" , ."
.. . .. f, () f. , . , g f, g , f, , , f, g.
Wenn Fehler auftreten, ist es natürlich möglich, den Kontrollfluss des Codes zu ändern, d.h. Übergang vom Körper einer Funktion zum Körper einer anderen. In diesem Fall können Sie in solchen Situationen globale Variablen mit globalen Funktionen verwenden.
PS In diesem Beitrag wurden nur 4 Arten von Fehlern berücksichtigt. Es gibt andere Fehlersituationen, die häufiger auftreten können als die oben beschriebenen.