字符串学习

sizeof 与 strlen

下面这样可以得到字符串大小
const unsigned char plaintext[] = “1dtr98h416r8hs6ergh6es14h6errh1s6e6h”;
sizeof(plaintext)

这样得到的字符串大小不对。
unsigned char * A_str = “123213”;
sizeof(A_str)
必须使用
strlen(A_str)


内存分配

malloc

malloc 用于分配指定大小的内存块,但不进行初始化
ptr = (int*) malloc(100 * sizeof(int));
返回指向分配内存块的指针,如果分配失败则返回 NULL。[2]
初始化:分配的内存块中的内容是未初始化的,可能包含垃圾值。

calloc

功能:calloc 用于分配指定数量和大小的内存块,并将分配的内存初始化为零.
语法:ptr = (int*) calloc(n, sizeof(int));
返回值:返回指向分配内存块的指针,如果分配失败则返回 NULL。
初始化:分配的内存块中的内容会被初始化为零。

realloc

功能:realloc 用于调整已分配内存块的大小。如果新分配的内存大于原内存,新分配的部分不会被初始化。[2]
语法:ptr = (int*) realloc(ptr, n * sizeof(int)); [2]
返回值:返回指向新分配内存块的指针,如果分配失败则返回 NULL。[2]
初始化:如果新分配的内存大于原内存,新分配的部分不会被初始化。[2]


野指针问题

1
2
3
4
5
6
7
8
9
10
11
12
struct Student {
int id;
char name[50];
float gpa;
};

int main() {
struct Student s = {0}; // 初始化所有成员为0
// 或者你可以部分初始化
struct Student s2 = {123, "John Doe", 3.8};
return 0;
}
1
2
3
4
5
6
7
8
typedef struct _Student {
int no
char *name;
}Student;

int main() {
Student s;
}

  1. 字符串数组: 字符串数组是一组字符串的集合,通常定义为一个二维字符数组。例如:
1
char strArr[3][20] = {"hello", "world", "!"};

在这个例子中,strArr是一个可以存储三个字符串,每个字符串的最大长度为19个字符(加上结束符\0)

  1. 字符串指针: 字符串指针是一个指向字符的指针,通常用于指向字符串的首字符。可以用来表示单个字符串,比如:
1
char *str = "hello";

这里,str指向了字符串”hello”的首字符。注意,这种方式定义的字符串是不可修改的,这是因为它通常在静态存储区中分配。

  1. char **(指向指针的指针): char **是一个指向字符指针的指针,通常用来表示字符串数组的动态分配。当你不确定字符串数量或者需要动态管理字符串时,可以使用char **。例如:
1
2
3
4
5
6
7
char **strArr; // 字符串数组
int n = 3; // 假设要存储3个字符串。
strArr = malloc(n * sizeof(char*)); // 分配指针数组

for (int i = 0; i < n; i++) {
strArr[i] = malloc(20 * sizeof(char)); // 为每个字符串分配内存
}
1
2
3
4
5
6
7
8
char* myString = malloc(50 * sizeof(char)); // 字符串
if (myString == NULL) {
fprintf(stderr, "Memory allocation failed\n");
return 1;
}

// 设置字符串内容
snprintf(myString, 50, "Hello, World!");

通过上面的例子,可以看到char **适用于更灵活的内存管理场景,而字符串数组则在大小固定的情况下使用更为方便。需要注意的是,使用动态内存时,最后需要通过free函数释放内存,以避免内存泄漏。