https://www.sejuku.net/blog/25002
I haven't written C language for about 10 years now, but it's crazy.
To be honest, I think there is a risk of damaging the brand.
I copied it from the article.
#include <stdio.h>
#include <stdlib.h>
//Structure declaration
typedef struct {
int num;
char *str;
} strct;
int main(void) {
//Generate entity
strct *entity;
//Allocate dynamic memory. Cast the allocated memory to the strct type pointer.
entity = (strct*)malloc(sizeof(strct));
//Member initialization
entity->num = 0;
entity->str = (char*)malloc(sizeof(32));
//Assign a string to memory
sprintf(entity->str, "%s %s!", "Hello", "World");
printf("%s\n", entity->str);
//Free memory
free(entity->str);
free(entity);
return 0;
}
The first thing to worry about is this comment
//Generate entity
strct *entity;
What did you mean by the substance? This is just a pointer ...
Personally, I like to initialize the variable at the same time as it is declared, so I would write it like this.
strct *entity = (strct *)malloc(sizeof(strct));
This area is still good. Here's the startling code.
entity->str = (char*)malloc(sizeof(32));
I don't think you understand what sizeof (32)
returns.
32 is an int type.
This is the same as sizeof (int)
, and it depends on the processing system, but I think that 4 is returned for most patterns.
In other words, I only have 4 bytes of memory, is that okay? (I'm not okay)
If you want to secure memory for 32 characters,
entity->str = (char *)malloc(sizeof(char) * 32);
I think I should write. Also, since memory allocation may fail, it is better to check the return value for NULL. No, you should.
//Assign a string to memory
sprintf(entity->str, "%s %s!", "Hello", "World");
I'm scared, and honestly, I don't think I'll write this kind of code in production, but there is a risk of buffer overflow. In fact, early code has a buffer overflow.
So much for this code, the next code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Structure declaration
typedef struct {
int num;
char *str;
} strct;
int main(void) {
//Generate entity
strct *entity;
//Allocate dynamic memory. Cast the allocated memory to the strct type pointer.
entity = (strct*)malloc(sizeof(strct));
//Member initialization
entity->num = 0;
entity->str = (char*)malloc(sizeof(32));
//Assign a string to memory
sprintf(entity->str, "%s %s!", "Hello", "World");
printf("%s\n", entity->str);
char arr_str[] = "Hello USA!";
//Memory size change
entity->str = (char*)malloc(sizeof(arr_str));
if(entity->str == NULL) {
printf("memory error");
return -1;
}
//Arr from the beginning of the address_Rewrite with NULL for the number of bytes of str
memset(entity->str, '\0', sizeof(arr_str));
printf("%s\n", entity->str);
//Free memory
free(entity->str);
free(entity);
printf("processing completion\n");
return 0;
}
Since I pointed out sizeof (32)
earlier, I will omit it.
//Memory size change
entity->str = (char*)malloc(sizeof(arr_str));
Hey, what about the original memory of ʻentity-> str`? It's the birth of a great memory leak.
Next!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Structure declaration
typedef struct {
int num;
char *str;
} strct;
int main(void) {
//Generate entity
strct *entity;
//Allocate dynamic memory. Cast the allocated memory to the strct type pointer.
entity = (strct*)malloc(sizeof(strct));
//Member initialization
entity->num = 0;
entity->str = (char*)malloc(sizeof(32));
//Assign a string to memory
sprintf(entity->str, "%s %s!", "Hello", "World");
printf("%s\n", entity->str);
//A copy of the entity of the structure
strct *copy_entity;
copy_entity = (strct*)malloc(sizeof(strct));
memcpy(copy_entity, entity, sizeof(strct)); //Member pointers are shallow copies
//Since it is a shallow copy, the value of the copy destination changes when the value of the copy source changes.
strcpy(entity->str, "Hello Japan!");
printf("%s, %s\n", entity->str, copy_entity->str);
//Individual members need to be copied to make a deep copy
copy_entity->str = (char*)malloc(sizeof(32));
strcpy(copy_entity->str, entity->str);
//Because of the deep copy, the copy destination value does not change even if the copy source value changes.
strcpy(entity->str, "Hello USA!");
printf("%s, %s\n", entity->str, copy_entity->str);
//Free memory
free(copy_entity->str);
free(copy_entity);
free(entity->str);
free(entity);
return 0;
}
sizeof (32)
is ... (omitted)
memcpy(copy_entity, entity, sizeof(strct)); //Member pointers are shallow copies
I'm not saying it's bad, but for this pattern, I would write * copy_entity = * entity
.
If you want to make a sample of memcpy, you may prepare an array of structures.
last!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Structure declaration
typedef struct {
int num;
char *str;
} strct;
int main(void) {
//Generate entity
strct *entity;
//Allocate dynamic memory. Cast the allocated memory to the strct type pointer.
entity = (strct*)malloc(sizeof(strct));
//Member initialization
entity->num = 0;
entity->str = (char*)malloc(sizeof(32));
//Assign a string to memory
sprintf(entity->str, "%s %s!", "Hello", "World");
printf("%s\n", entity->str);
//A copy of the entity of the structure
strct *copy_entity;
copy_entity = (strct*)malloc(sizeof(strct));
memcpy(copy_entity, entity, sizeof(strct)); //Member pointers are shallow copies
//Comparison operation between copy source and copy destination
if( memcmp(entity, copy_entity, sizeof(©_entity)) == 0) {
printf("Structure entity%s and%s is the same\n", "entity", "copy_entity");
} else {
printf("Structure entity%s and%s is different\n", "entity", "copy_entity");
}
//To make a deep copy, you need to copy the member alone
copy_entity->str = (char*)malloc(sizeof(32));
strcpy(copy_entity->str, entity->str);
//Comparison operation between copy source and copy destination
if(memcmp(entity, copy_entity, sizeof(©_entity)) == 0) {
printf("Structure entity%s and%s is the same\n", "entity", "copy_entity");
} else {
printf("Structure entity%s and%s is different\n", "entity", "copy_entity");
}
//Free memory
free(copy_entity->str);
free(copy_entity);
free(entity->str);
free(entity);
return 0;
}
Is this code okay? (So it's not okay)
//Comparison operation between copy source and copy destination
if( memcmp(entity, copy_entity, sizeof(©_entity)) == 0) {
printf("Structure entity%s and%s is the same\n", "entity", "copy_entity");
} else {
printf("Structure entity%s and%s is different\n", "entity", "copy_entity");
}
In particular, sizeof (& copy_entity)
Do you understand this meaning?
The type of copy_entity is strct *
, right? What happens if you add &
to it?
Yes! Represents the strct **
type.
So what is that sizeof
? ?? ??
・ ・ ・
It depends on the processing system, but in most cases, 4 or 8 will be returned.
In other words, I think I'm comparing only the part of the structure that corresponds to ʻint num... If I had to rewrite it, it would be
sizeof (strct). Even if you make a mistake, it's not
sizeof (copy_entity)`!
By the way, I'm talking about padding, so I think it's better to allocate memory for the structure and then initialize it using memset
.
To be honest, I think it's better to create a comparison function and check the contents of the members instead of comparing with memcmp
. In C ++, it's an overload of the = operator.
Finally··· Everyone makes mistakes. Hate the code, don't hate people. It's scary if you don't repeat the verification of technical articles.
Recommended Posts