使用strcpy和将字符串的地址等同起来有什么区别?

时间:2019-06-16 07:17:51

标签: c pointers

我无法理解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);

3 个答案:

答案 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

  1. 分配的内存(带有malloc())的地址将丢失。 (这会导致内存泄漏-堆中的内存无法通过代码中的任何指针进行寻址。)

  2. 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;----------------|
  
      
  1. strings是一个指针数组,每个指针必须指向有效内存。

  2.   
  3. 由于strings[i]不会指向有效内存,因此将导致未定义的行为。

  4.   
  5. 有效,但是strings的每个指针都指向相同的位置,因此每个指针都具有相同的内容。
  6.   
  7. 因此,首先创建新内存,将内容复制到其中,然后将该内存分配给strings[i]
  8.   

答案 2 :(得分:1)

strcpy将特定的字符串复制到分配的内存中。分配指针实际上并不会复制字符串,只是将第二个指针变量设置为与第一个相同的值。

strcpy(char *destination, char *source);

从源复制到目标,直到函数找到'\ 0'。此功能不安全,不应该使用-尝试使用strncpystrlcpy。您可以在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)上分配的项目,因为函数结束时,编译器会为您处理。