【问题标题】:Deleting an element in the middle of array?删除数组中间的元素?
【发布时间】:2015-12-15 08:20:34
【问题描述】:

我试图从数组中间删除一个元素,然后移动整个内容,但我遇到了一些困难,因为我的测试数组不是“正确的”。我通过使用 strcpy 用字符串填充数组来解决问题。 strcpy 上面的注释部分是我之前使用的方法(不起作用)。有人可以解释一下为什么它不起作用吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){

    char *array;
    int i=5;

    array = (char*)calloc(1024, sizeof(char));

    if(array == NULL){
        printf("Out of memory\n");
        return 0;
    }

    //array = "Just some test string";
    strcpy(array, "Just some test string");

    printf("%s\n", array);

    memmove(array+i+1, array+i, strlen(array)-i);
    array[i] = ',';

    printf("%s\n", array);

    memmove(array+i, array+i+1, strlen(array)-i);

    printf("%s\n", array);

    free(array);

return 0;
}

printf 通常在注释部分工作,但是 memmove() 使我的程序崩溃!

【问题讨论】:

  • 请不要将calloc 投射到= 的右侧。这是不必要的,有时是有害的。
  • 您忘记移动空终止符,其他一切正常。当然,如果你扩大这个玩具应用程序,你需要做一些预检查,确保你的移动不会溢出缓冲区,并且i 小于字符串的大小。
  • @Bathsheba 你到底是什么意思?这是符合标准的,否则我会收到警告
  • @M.M 是的,谢谢,这只是一个测试用例:P

标签: c arrays memory-management dynamic-arrays


【解决方案1】:

如果你有这个:

array = "Just some test string";

然后

1) 由于覆盖了calloc'ed 指针,您拥有memory leak

2) 您正在尝试修改字符串文字。这可能就是它崩溃的原因。修改字符串文字是undefined behaviour。它们通常存储在只读存储器中。由于strcpy() 制作了字符串文字的副本,因此它按预期工作并且此方法失败。

【讨论】:

  • 所以基本上我的 *array 被转换为堆栈上字符串文字的指针?
  • array 一个指针。当为它分配一个字符串文字时,它会被转换为一个指针。例如。 char *p = "Hi"; 将字符串文字的地址分配给p
【解决方案2】:

在这些陈述中

memmove(array+i+1, array+i, strlen(array)-i);
array[i] = ',';

尝试在5 位置插入字符',',因为变量i 被初始化为5。

所以字符串的包括终止零的部分必须从这个位置开始向右移动。部分的长度是

strlen( array ) - i + 1

因为终止零也必须移动。

所以这些语句看起来像

memmove( array + i + 1, array + i, strlen( array ) - i + 1 );
array[i] = ',';

然后在这些陈述中

memmove( array + i, array + i + 1, strlen( array ) - i );

这个说法是正确的。表达式strlen( array ) - i 计算如下

( strlen( array ) + 1 ) - ( i + 1 )

至于这个说法

array = "Just some test string";

然后指针array 指向一个字符串字面量,尽管C 中的字符串字面量具有非常量字符数组的类型,但它们是不可变的。

任何修改字符串文字的尝试都会导致程序的未定义行为。

此外,如果在此语句之前,您还使用调用 calloc 的结果初始化了此指针,那么将存在内存泄漏,因为指针被重新分配并且分配的内存地址丢失。

【讨论】:

  • 感谢您的回答。根据你的逻辑,我最后也需要 +1 memmove(array + i, array + i + 1, strlen(array) - i);我是这样算的,strlen(array) = 21;//所以没有'\0'字符,从0 + 5 = 6//第6个元素开始,移动21-5=17个元素就包括了'\0'右边:) ?
  • @Maxitj 函数 strlen 返回终止零之前的字符数。但是如果你想移动字符串的一部分,你需要考虑终止零,因为它也应该被移动。在您的原始代码中,您使用了 calloc ,它用零初始化所有内存。所以右移是没有问题的。但是左移会有问题,因为终止的零不会移动。
【解决方案3】:

我试图做这样的事情。

我解决了这个问题:

    *(array+strlen(string)+1)=0;

Null 终止字符串,但如果后续的 printf() 正常工作,这将无济于事。

否则请参阅: http://www.java-samples.com/showtutorial.php?tutorialid=591

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 2013-08-06
    • 2011-10-31
    • 2020-04-28
    • 2018-01-30
    相关资源
    最近更新 更多