【问题标题】:Pointer arithmetic segmentation issue指针算术分段问题
【发布时间】:2016-08-19 02:42:00
【问题描述】:
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

 int string_cmp(const void *p, const void *q);

 int main(int argc, char **argv)
 {
    int i;   // variable
    char **words_array = malloc(sizeof(char*)*(argc+1)); // sets new array to hold the words
    char *p; // another char pointer array
    p = *words_array;       // set both equal to eachother

    for(; *p < (argc - 1); p++) // for loop
    {
            p = malloc(strlen(*argv) + 1); // determines size based on user input
            argv++; // increments
            strcpy(p++, *argv); // copies words to the new array

    }
    p = NULL; // resets p

    qsort(words_array, argc-1, sizeof(char *), string_cmp); // sorts the array
    for(i = 0; i < argc - 1; i++){ // for loop to print properly
            printf("%s ", words_array[i]);
    }
    printf("\n");
    return 0;
  }

 int string_cmp (const void *p, const void *q) // compares the two different          strings and returns a value
{
    const char *value = *(const char**)p;
    const char *value_two = *(const char**)q;

    return strcmp(value, value_two);
}

所以我的程序应该接受命令行参数并返回它们使用 Qsort 排序。示例是“./a.out 你好黑暗我的老朋友应该作为黑暗朋友你好我的老朋友返回。我没有收到任何编译器错误但是我得到一个分段错误,我不知道如何解决这个问题我的指针算术。

【问题讨论】:

  • p = *words_array; words_array 的 malloc 在哪里?
  • 你为什么将 words_array 声明为指向指针的指针?
  • @sjsam malloc 在声明 **words_array 时就在那里
  • @RamblinRose,有没有更简单的方法或者我该如何解决?
  • 使用不确定的对象值的未定义行为。

标签: c pointers segmentation-fault pointer-arithmetic


【解决方案1】:

你正在增加双指针(argv),即;

for(; *p < (argc - 1); p++) // for loop
{
        p = malloc(strlen(*argv) + 1); // determines size based on user input
        argv++; // increments
        strcpy(p++, *argv); // copies words to the new array

}

所以把它改成 (*argv)++

【讨论】:

  • 仍然出现分段错误
【解决方案2】:

问题出在你的 for 循环中。您将*pargc 进行比较,这毫无意义。将循环替换为标准计数器i

for (i = 1; i < argc; i++)

请注意,应该使用argc,而不是argc - 1,并且循环应该从1开始,而不是从0开始。 另外,在循环中你可以使用argv[i]而不是*argv

【讨论】:

    【解决方案3】:

    这些是一些建议:

    char** argv 更改为char* argv[]

    argc 返回比实际传递的参数数量多一。额外的计数是针对可执行文件名称本身的。

    所以最好做一些错误检查,做:

    argc--;
    if(argc > 0) // We have some arguments
    {
    /* Do something 
     * char **words_array = malloc(sizeof(char*)*(argc+1)
     * may be changed to 
     */
      char **words_array;
      words_array=malloc(argc*sizeof(char*));
    /* Coming down 
     * You could change that for-loop to something like this.
     */
     for(int i=0;i<argc;i++)
         words_array[i]=argv[i]; //  You have all the arguments stored in words_array
    /* Now go on sort words_array
     * and so and so forth
     */    
    
    }
    

    【讨论】:

    • 为什么一开始就递减argc?
    • 支持你做./your_program_name Romeo Juliet然后argc返回3。argc也算your_program_name。所以我一开始就递减它,使它等于你传递的实际参数数量。
    • 好吧,还有一个问题是我的 char **words_array 等于 malloc 并且我不应该使用 double ** 吗?还是您只使用一个有什么原因?
    • 我也更改了代码来尝试,但现在它说我的 qsort 中的 words_array 未声明?我不明白发生了什么变化
    • 假设您有 char* c 并且您希望分配一些内存,您将使用 malloc(some_number*sizeof(char))。考虑到上述 malloc 在您的系统中 char 是一个字节,您会说“好的!我希望为 c 分配一些字节数”。希望这很清楚。现在有了 char**c,你就有了一个指向 char 的指针。您需要malloc 2 次。首先是c=malloc(some_number*sizeof(char*)),然后是*c=malloc(some_number*sizeof(char))。我在对您的问题的评论中提到了这一点。 char**char*[] 是有原因的,main 的参数只能是字符串。
    猜你喜欢
    • 2011-02-03
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多