【问题标题】:segmentation fault when manipulating strings?操作字符串时出现分段错误?
【发布时间】:2015-01-04 19:39:12
【问题描述】:

这段代码总结了我遇到的问题。我想将文件从源复制到指定的目标,我可以更改它的名称它是一个集成在我正在尝试创建的应用程序中的函数管理文件

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

 void concatenate_string(char *original, char *add)
{
   while(*original!='\0')
     original++;

   while(*add!='\0')
     {
        *original = *add;
         add++;
         original++;
     }
     *original = '\0';
}

 int main(int argc,char *argv[])
  {

    char *nom;
    char *path;
    printf("entrer a name \n");
    scanf("%s",nom);
    printf("entrer a pathh \n");
    scanf("%s",pathh);
    char *dest=(char*)malloc(strlen(nomm)+46+1);
    strcat(dest,"/home/ridaamine/Desktop/app/application/Files/");
    strcat(dest,nom);
    char *comand=(char*)malloc(strlen(name)+8+strlen(path)+1);
    strcat(comand,"cp -via ");
    strcat(comand,path);
    strcat(comand," ");
    strcat(comand,name);
    system(comand);
  }

【问题讨论】:

  • 使用strcat(dest,"..."); 不会成功,因为字符串dest 尚未初始化为空字符串。序列应该是malloc(...); strcpy(...); strcat(...)comand 同上。

标签: c string segmentation-fault


【解决方案1】:

你没有初始化nom

scanf("%s",nom);

要么

nom = malloc(SOME_SIZE);

然后,假设SOME_SIZE == 100

scanf("%99s", nom);

char nom[SOME_SIZE];

然后,让我们说SOME_SIZE == 100

scanf("%99s", nom);

当然这同样适用于path

第二种解决方案更好,因为它更快not that much,并且您在使用后不需要free(nom)。在极少数情况下可能需要第二种情况,因为字符串的大小太大(> 8M)会溢出堆栈。

正如Weather Vane指出strcat也有问题,你应该第一次使用strcpy

strcat(dest,"/home/ridaamine/Desktop/app/application/Files/");
strcat(dest,nom);

应该

strcpy(dest,"/home/ridaamine/Desktop/app/application/Files/");
strcat(dest,nom);

很明显,这一次同样适用于command

你终于有了一个你没有计入的空间

malloc(strlen(dest) + 8 + strlen(path) + 1 + 1 /* space " " */)

提示:您不需要投射malloc,所以不要,它可能隐藏一个潜在的错误。在取消引用指针之前,请务必检查 malloc 是否返回 NULL

你也应该在完成后免费调用,这是你自己的代码修复

 int main(int argc,char *argv[])
  {

    char nom[100];
    char path[100];
    char _path[] = "/home/ridaamine/Desktop/app/application/Files/";
    char cp[] = "cp -via ";
    char space[] = " ";

    printf("entrer a name \n");
    scanf("%99s", nom);
    printf("entrer a path \n");
    scanf("%99s", path);

    char *dest = malloc(strlen(nom) + strlen(_path) + 1);
    if (dest == NULL)
    {
        printf("no more memory left.\n");
        return -1;
    }       
    strcpy(dest, _path);
    strcat(dest, nom);

    char *comand = malloc(strlen(dest) + strlen(cp) + strlen(space) + strlen(path) + 1);
    if (command == NULL)
    {
        free(dest);
        printf("no more memory left.\n");
        return -1;
    }

    strcpy(comand, cp);

    strcat(comand, path);
    strcat(comand, space);
    strcat(comand, dest);

    free(dest);
    system(comand);
    free(command);

    return 0; // always return from main
  }

【讨论】:

  • 我尝试了第二个,但是当它完成并将命令发送到系统时我仍然遇到问题,我得到一个分段错误
  • 确保字符串长度足够长——除非你在嵌入式平台上,否则不要吝啬内存。
  • 如果我分配 50 个字符,我的意思是多少,这是否意味着我可以存储 50 个字符或者什么,因为我认为这已经足够了
  • 第一个字符串dest 只为路径名分配了足够的内存,所以它会在你的第二个strcat() 上中断。为什么不加倍你认为它需要的 - 甚至更好地添加字符串长度而不是硬编码。
  • @RidaAmine,不要分配超过所需的内存,这可能会隐藏错误。只需检查我的答案更新,strcat 一个你不算数的“”。
【解决方案2】:

第一个strcat() 必须在每种情况下更改为strcpy(),因为字符串尚未初始化为空字符串。而且第一个字符串dest肯定会太短。

char *dest=(char*)malloc(strlen(nomm)+46+1);    // this is too short
strcpy(dest,"/home/ridaamine/Desktop/app/application/Files/");
strcat(dest,nom);

char *comand=(char*)malloc(strlen(name)+8+strlen(path)+1);
strcpy(comand,"cp -via ");
strcat(comand,path);
strcat(comand," ");

【讨论】:

  • @iharob 把人们的 cmets 放在你的答案中并不是很好的形式。
  • 这还不错,你可以先发布答案,我不会从你那里拿走它,但你让我认为答案是好的,但我只是错过了,请注意我的第一个问题提到首先发生,当我写答案时我还没有达到那部分,但我承认你的评论让我更快地看到了这一点。您可以从我这里找到有助于提高答案本身质量的答案的 cmets,有时我对同一个问题有答案,我也会进行编辑以改进我也回答过的问题的答案。
  • 我想,这就是 cmets 的用途。我给你的答案 +1,你确实发现了一个问题,但不是全部。
  • 确实如此,但这是您急于获得第一个答案然后添加越来越多内容的另一个场合。
  • 是的,但我没有提及您已经说过的内容。我赞成@iharob 的正确答案。
猜你喜欢
  • 2019-08-21
  • 2015-05-20
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
相关资源
最近更新 更多