繁体   English   中英

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

[英]What is the difference between using strcpy and equating the addresses of strings?

我无法理解strcpy函数和使用指针等效字符串地址的方法之间的区别。下面给出的代码将使我的问题更加清晰。 任何帮助,将不胜感激。

//code to take input of strings in an array of pointers
#include <stdio.h>
#include <strings.h>
int main()
{
    //suppose the array of pointers is of 10 elements
    char *strings[10],string[50],*p;
    int length;
    //proper method to take inputs:
    for(i=0;i<10;i++)
    {
        scanf(" %49[^\n]",string);
        length = strlen(string);
        p = (char *)malloc(length+1);
        strcpy(p,string);//why use strcpy here instead of p = string
        strings[i] = p; //why use this long way instead of writing directly strcpy(strings[i],string) by first defining malloc for strings[i]
    }
return 0;
}

关于指针魔力的简短介绍:

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

在复制C字符串string到内存中指出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

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. 将导致未定义的行为,因为strings[i]没有指向有效的内存。

  3. 可以工作但strings每个指针都指向相同的位置,因此每个指针都有相同的内容。
  4. 因此,首先创建新内存,将内容复制到它并将该内存分配给strings[i]

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]是一个指针 - 你已经分配了一个包含10个指针的数组,每个指针的每个元素( strings[1]strings[9]等等) )必须在使用前分配。

您可以立即分配的唯一一个是string ,因为该空间已经分配。 这些指针中的每一个都可以通过下标来解决 - 但是在每种情况下,您必须确保不会走到最后,否则您将导致SIGSEGV“分段违规”,并且您的程序将崩溃。 或者至少,它应该,但你可能只会得到奇怪的结果。

最后,必须手动释放分配给的指针,否则你将有内存泄漏。 不需要释放在堆栈( string )上分配的项目,因为编译器在函数结束时为您处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM