Salutations, chers lecteurs. Dans cet article, vous apprendrez comment éviter les erreurs les plus courantes lors de la programmation en C.
Utilisation incorrecte du caractère de fin de ligne (caractère nul '\ 0')
Considérez le code suivant:
#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);
}
Dans ce code, nous obtiendrons les résultats suivants
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.
Bien sûr, lorsque des erreurs se produisent, il peut y avoir des situations où le flux de contrôle du code est modifié, c'est-à-dire transition du corps d'une fonction au corps d'une autre. Dans ce cas, dans de telles situations, vous pouvez utiliser des variables globales avec des fonctions globales.
PS Dans cet article, seuls 4 types d'erreurs ont été considérés. Il existe d'autres situations d'erreur qui peuvent se produire plus souvent que celles décrites ci-dessus.