Greetings, dear readers. In this post, you will learn how to avoid the most common mistakes when programming in C.
Incorrect use of end-of-line character (null character '\ 0')
Consider the following 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 this code, we will get the following results
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.
Of course, when errors occur, it is possible to change the control flow of the code, i.e. transition from the body of one function to the body of another. In this case, in such situations, you can use global variables with global functions.
PS In this post, only 4 types of errors were considered. There are other error situations that may occur more often than those described above.