为什么不能在 C 中的 get 中使用指针?比如 char *str 替换 get(str) 中的 char str[40]

问题描述

CREATE FUNCTION yourDataset.getValue(input STRING,key STRING)
RETURNS STRING
LANGUAGE js
AS """
// JavaScript code to read the data
""";

在上面的代码中,如果将str替换为一个指针,char *str。那么NULL就出来了。假设gets由char *gets(char *str)定义,它应该使用指针而不是数组。我看到的所有例子都是数组而不是指针。谢谢。

解决方法

function gets() 已弃用,您的 libc/编译器可能会忽略它。尝试改用 fgets()

#include <stdio.h>

int main () 
{
    char str[40];
    printf("Enter a string : \n");
    if (fgets(str,sizeof(str),stdin) != NULL)
    {
        printf("You entered: %s\n",str);
    }

    return 0;
};

此外,如果您不想使用堆栈,则需要提供指向已分配空间的指针。在代码中 str 也可以是 char *str = malloc(40); 然后将 sizeof(str) 更改为 40 因为 str 不再是堆栈。

,

非常有趣的问题,我被问过很多这个问题!

你应该有一点指针和记忆的背景来理解正在发生的事情。

首先让我们简要回顾一下指针和内存:

  • 我们的计算机有一些内存,我们可以在编程中使用它,我们可以在编程中使用它,我们存储的任何东西(在运行时)例如 int、双精度数组、一些复杂的结构和字符串(它们是数组字符)应该在内存中的某个地方。
  • 指针包含内存中某处的地址,有些指针知道该内存(如何读/写值),有些则不知道。
  • 指针 (NULL) 有一个特殊值,表示 nowhere,如果指针指向 NULL,则该指针并非无处指向(显然 nowhere 不是内存中的有效地址)
  • array 是一种特定类型的指针,一个 const 指针,指向已分配的内存在堆栈中。

以及关于 gets 函数:让我们认为我们想要重新实现这样的函数(即 my_gets),我们应该怎么做?如何返回一个字符串(字符数组)? 这些是选项(据我所知):

  • 在我们的函数中创建一个本地数组并填充它。那我们应该退货吗?不,我们不能!因为该数组在我们函数的堆栈中,并且在函数结束后,我们的函数数据包括这个数组将自动弹出(由编译器处理)。 虽然没有人禁止我们返回那个数组,但这会导致悬空指针问题。
  • 分配一些空间而不是堆栈(堆)并填充它。这很好,有方法可以做到这一点!例如 readline (不在 ansi c 中,你可以找到它 here)会这样做。这种方法的缺点是您应该处理该内存并稍后释放它,这也可能不是最佳方式,您可能应该将该字符串复制到您已经分配的内存中
  • 最后一种方法(以及使用的方法)是获取一个已经指向有效内存的指针并填充该内存。您已经知道 get 需要一个指针作为输入,我补充说,该指针应该指向一个有效且可访问的内存,该内存可以填充它。如果指针指向 NULL(或者可能未初始化并指向一些随机位置)获取将写入失败并导致未定义的行为(例如分段错误)

最后几点:

  • 数组解决方案有效,因为数组名称是指向有效内存(堆栈中的数组)的指针,因此它可以且易于理解。
  • 如果我们不想使用数组,我们可以将我们的指针指向一个有效的内存,我们需要使用 malloc/calloc 来分配一块内存。看到这个:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int size = 40 * sizeof(char);
    char* p = malloc(size);
    printf("Enter a string : \n");
    if (fgets(p,size,stdin) != NULL) {
        printf("You entered: %s\n",p);
    }

    free(p);
    return 0;
}

  • gets 是不安全的,因为它不关心我们有多少内存,它一直写到字符串结束并且可能导致缓冲区溢出,更好的选择(正如人们所说)是 fgets 因为它关心内存大小并且不会超过。但我的回答并不关心它是 fgets 还是 gets。