【问题标题】:How to qsort char**?如何qsort char**?
【发布时间】:2023-03-22 19:41:01
【问题描述】:

我想对声明如下的字符串数组进行排序:

char** s;
s = calloc(4, sizeof(char *));
s[0] = "Banana";
s[1] = "Apple";
s[2] = "Grape";
s[3] = "Strawberry";

为此我使用了 qsort 函数:

size_t len = sizeof(s) / sizeof(char *);
qsort(s, len, sizeof(char *), cmp);

cmp 看起来像这样:

int cmp(const void* s1, const void* s2)
{
    const char** a = (const char**) s1;
    const char** b = (const char**) s2;
    return strcmp(*a, *b);
}

但是,对于此代码,没有任何内容进行排序,并且输出的顺序与数组中的顺序相同。问题是,我用另一种方式检查了它,我将数组声明为(qsort 和 cmp 保持不变):

char* s[] = {"Banana", "Apple", "Grape", "Strawberry"};

并且输出已完美排序。我有点理解是因为,第一种方法是双(指针指针)指针,第二种方法是指向数组的指针,但它们的工作原理是相同的。任何想法如何排序 char** s?先谢谢了

【问题讨论】:

  • 你没有为 s 中的每个 char* 分配任何东西。而底部示例是在堆栈上分配的。
  • @JoshAbraham 在这个非常特殊的情况下,这些是字符串文字并且被神奇地分配。
  • @EugeneSh。作为 cmp 的参数代表 void* 指针,这没关系。但是,为了获取字符串,我正在使用这种方法。而且,我看了很多资源,都在做同样的方法
  • @MiradilZeynalli 对。忽略我的第一条评论(无论如何都删除了..)。
  • @JoshAbraham 不在 cmets 中。搜索有关使用字符串文字初始化指针的信息,有很多关于它的问题。

标签: c arrays string sorting pointers


【解决方案1】:

此代码是正确的代码。char* s[] = {"Banana", "Apple", "Grape", "Strawberry"}; 是正确的,并且会按照您的预期运行。

明确声明 - 您对sizeof 的使用是有效的,不会有问题。 数组在此处不会衰减当用作 sizeof 的操作数时。

char ** 确实是正确的。每个元素的地址都被传递给cmp 函数。

故障是 :-

如果char** s = calloc ... 使用sizeof 是错误的,因为它是一个包含已分配块地址的指针。您无法知道分配给它的内存量。因此,当您将代码与char**s = calloc .. 一起使用时,请指定数组的大小(不使用sizeof),它会起作用。

有没有办法让 len 成为 char** 案例所需的大小?

是的。您需要将其单独保存在变量中。您不能应用 sizeof 并从指针变量中获取分配的内存大小。

如何使两者都工作?

如前所述,其他所有内容(比较器函数等)都是相同的,只是现在您必须跟踪分配了多少,并将其传递给qsort。您已经使用4 的硬编码值分配内存量。创建一个变量const int size = 4,然后保留它并相应地使用它。

长话短说 - 问题在于获取要排序的元素数量的大小。

【讨论】:

  • calloc 函数没有错误,我已经在其他项目中检查过大小,它存储了所需数量的字符串。但我还是不明白,如何 qsort char**
  • @MiradilZeynalli.: 你不能在指针上应用sizeof 并期望它返回分配内存的大小!那就是你错了。
  • 跟踪数组的大小工作。非常感谢)
【解决方案2】:

您遇到的问题是变量len。当您想通过malloc()calloc() 等函数分配内存时,最好使用变量来分配要分配的内存大小。所以不要写:

char** s;
s = calloc(4, sizeof(char *));

写:

size_t szAlloc = 4;
char **s = calloc(szAlloc, sizeof(char *));

这样,您可以跟踪分配的内存,并在需要时使用此值。由于变量s 被声明为指针,因此在其上应用运算符sizeof() 将产生该指针的大小,而不是calloc() 分配的内存大小,然后将其除以sizeof(char *) 将得到@结果是987654330@。

使用变量szAlloc,您可以调用qsort()

qsort(s, szAlloc, sizeof(char *), cmp);

这应该会给出正确的结果。

【讨论】:

    【解决方案3】:

    在第一种情况下,由于s 是一个指针,sizeof(s) 会给你指针的大小,而不是它指向的大小。这当然会导致len 等于1(指针大小除以指针大小)。

    在第二种情况下,s 不再是一个指针,而是一个由四个元素组成的数组。它的类型是char*[4]

    您只能对实际数组使用 sizeof-division “技巧”。

    如果您想使用指针和动态分配的“数组”,您需要自己跟踪元素的数量。

    【讨论】:

    • 有没有办法让 len 成为 char** 案例所需的大小?
    • @MiradilZeynalli 不,您必须自己跟踪。
    • 感谢您的帮助)
    猜你喜欢
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 2020-05-09
    • 2018-02-18
    • 2021-12-15
    相关资源
    最近更新 更多