我无法理解strcpy函数和使用指针将字符串的地址相等的方法之间的区别。下面给出的代码将使我的问题更加清楚。任何帮助将不胜感激。
final OffsetDateTime dateTime = OffsetDateTime.parse("2009-07-30T16:10:36+06:00");
final OffsetDateTime utcDateTime = dateTime.withOffsetSameInstant(ZoneOffset.UTC);
final String formatted = utcDateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"));
System.out.println(formatted);
答案 0 :(得分:1)
指针魔术的简短介绍:
char *strings[10],string[50],*p;
这是三个具有不同类型的变量:
char *strings[10]; // an array of 10 pointers to char
char string[50]; // an array of 50 char
char *p; // a pointer to char
然后完成跟踪(10次):
scanf(" %49[^\n]",string);
从输入中读取C字符串并将其存储到string
中,考虑到也必须插入0终止符。
length = strlen(string);
计算非0字符,直到找到0个终止符并存储在length
中。
p = (char *)malloc(length+1);
在堆上分配长度+ 1(用于0终止符)的内存,并将该内存的地址存储在p
中。 (malloc()
可能会失败。支票if (p != NULL)
不会造成伤害。)
strcpy(p,string);//why use strcpy here instead of p = string
将string
中的C字符串复制到p
中指向的内存中。 strcpy()
复制,直到在源中找到(包括)0终止符为止。
strings[i] = p;
将p
(指向内存的指针)分配给strings[i]
。 (赋值strings[i]
指向的内存与p
相同。赋值是指针赋值,而不是指向的值的赋值。)
为什么用strcpy(p,string);
代替p = string
:
后者会将string
(本地变量,可能存储在堆栈中)的地址分配给p
。
分配的内存(带有malloc()
)的地址将丢失。 (这会导致内存泄漏-堆中的内存无法通过代码中的任何指针进行寻址。)
p
现在将指向string
中的局部变量(对于for
循环中的每个迭代)。因此,之后,strings[10]
的所有条目最终都指向string
。
答案 1 :(得分:1)
char *strings[10]---- --------->1.
strcpy(strings[i],string) ----->2.
strings[i] = string ----------->3.
p = (char *)malloc(length+1); -|
strcpy(p,string); |-> 4.
strings[i] = p;----------------|
strings
是一个指针数组,每个指针必须指向有效内存。由于
strings[i]
不会指向有效内存,因此将导致未定义的行为。- 有效,但是
strings
的每个指针都指向相同的位置,因此每个指针都具有相同的内容。- 因此,首先创建新内存,将内容复制到其中,然后将该内存分配给
strings[i]
答案 2 :(得分:1)
strcpy
将特定的字符串复制到分配的内存中。分配指针实际上并不会复制字符串,只是将第二个指针变量设置为与第一个相同的值。
strcpy(char *destination, char *source);
从源复制到目标,直到函数找到'\ 0'。此功能不安全,不应该使用-尝试使用strncpy
或strlcpy
。您可以在https://linux.die.net/man/3/strncpy中找到有关这两个功能的有用信息-检查代码将在何处运行,以帮助您选择最佳选择。
在代码块中,您具有此声明
char *strings[10],string[50],*p;
这声明了三个指针,但是它们完全不同。 *p
是一个普通指针,必须使用malloc
为它分配空间,然后才能使用它。 string[50]
也是一个指针,但长度为50(字符,通常为 1个字节),并且直接分配在函数堆栈上,因此您可以立即使用它(尽管第一次使用除非您使用过像Solaris'calloc
这样的清零分配器,否则应该将内存清零。最后,*strings[10]
是 double 指针-您已经分配了一个数组,共10个指针,每个元素(strings[1]
,strings[9]
等)必须在使用前分配给它们。
您可以立即分配给他们的唯一一个是string
,因为已经分配了空间。这些指针中的每一个都可以通过下标进行寻址-但是,在每种情况下,您都必须确保不要走到尽头,否则会发生SIGSEGV“分段违规”,并且程序将崩溃。或至少应该如此,但您可能只会得到怪异的结果。
最后,必须手动释放分配给的指针,否则会发生内存泄漏。不需要释放在堆栈(string
)上分配的项目,因为函数结束时,编译器会为您处理。