返回时指针崩溃 - C.

时间:2013-09-05 01:40:47

标签: c string pointers segmentation-fault

我正在努力完全理解指针,所以我正在研究Kenneth的A. Reek书,“Pointers On C.” 我在处理第6章问题1时遇到了一个问题: “编写一个函数,搜索字符串中任何一个给定的字符集。你的函数应该匹配这个原型

 char *find_char(char const *source, char const *chars);

这是我的问题:在这个while循环中,

while(*found_char_location != '\0'){

    if(*found_char_location == *source_pt_cpy)
    {
        return found_char_location;
        //return *source_pt_cpy;
    }//end if

如果我尝试返回指针 * source_pt_cpy ,程序会给我一个分段错误错误,但如果我返回指针 * found_char_location 这会很麻烦,因为他们没有相同的价值?为什么一个会崩溃而另一个不会崩溃? 这是我的完整源代码。感谢您的帮助。

char *find_char(char const *source, char const *chars)
{

  if(is_null(source, chars))
  {

    return NULL;
  }//end if

  char *found_char_location;
  char *source_pt_cpy;

  found_char_location = chars;

  source_pt_cpy = source;

  while(*found_char_location != '\0'){

    if(*found_char_location == *source_pt_cpy)
    {
      return found_char_location;
      //return *source_pt_cpy;
    }//end if

    source_pt_cpy++;

    if(*source_pt_cpy == '\0')
    {
      chars++;
      source++;
      found_char_location = chars;
      source_pt_cpy = source;
    }//end if

  }//end while

  return NULL;
}//end function

4 个答案:

答案 0 :(得分:0)

他们指向的东西是相同的值,但它们不在同一个位置(或者你不需要检查它们的值是否相同)。

另外,小心使用*; * source_pt_cpy不是指针,它指向的是什么,如果那是你要返回的,那么使用该值作为指针很可能会导致seg错误。

答案 1 :(得分:0)

分段错误可能是由find_char引起的,但在函数的调用者中发生。请注意,在一种情况下(有效的情况),您返回一个指针,调用者可能需要一个指针,因为这是正确的:

return found_char_location;

如果失败,你不会返回指针,但实际上只是指针所指向的字符:

return *source_pt_cpy;

因此,如果调用者将其视为指针,则可能会导致分段错误。

答案 2 :(得分:0)

通常 * chars 字符串会短于 * source 字符串。

您应该通过字符循环来源

中的固定位置

如果找不到匹配项,请使用 source ++

进入源代码中的下一个位置

但是

返回字符

的开头

使用类似的东西:

chars = beginChars ;

你没有做的事。

如果您不确定发生了什么,请添加:

printf(" %c %c\n",*source,*chars);

在循环中间,在所有增量和减量之后。

答案 3 :(得分:0)

在C中,指针是变量的地址,没有别的。如果您想比较字符串(在C中翻译为空终止字符串),最好使用strcmp()strncmp()函数。

像这样的陈述

  char *found_char_location;
  char *source_pt_cpy;

  found_char_location = chars;

  source_pt_cpy = source;
  ...
  ...
    if(*found_char_location == *source_pt_cpy)

会比较存储在found_char_locationsource_pt_cpy指针指向的位置的单个值,在这种情况下是一个字符,我认为这不是你想要的!

以下是来自a home-brewed string library I maintain的代码段(如果您想通过指针获得乐趣,请查看它!)

/*******************************************************************
*  Return values
*      - NULL in case any of the arguments is NULL
*      - Modified string is returned 
*
*  Example Usage
*      char str[] = "'free' as in 'free speech', not as in 'free beer'";
*      printf("%s\n",zstring_replace_str(str,"free","KLMN"));
*
*  Example Output
*      'KLMN' as in 'KLMN speech', not as in 'KLMN beer'";
******************************************************************/
char *zstring_replace_str(char *str, const char *x, const char *y){
    /* to preserve the address of original pointers, tmp_ are used 
     * dummy_ptr enables us to preserve the address of tmp_str when
     * a matching string pattern is found
     * */
    char *tmp_str = str, *tmp_x = x, *dummy_ptr = tmp_x, *tmp_y = y;
    int len_str=0, len_y=0, len_x=0;

    /* NULL pointer check */
    if ((*str && *x && *y)==0)
        return 0;

    /* calculating length of strings */
    for(; *tmp_y; ++len_y, ++tmp_y)
        ;

    for(; *tmp_str; ++len_str, ++tmp_str)
        ;

    for(; *tmp_x; ++len_x, ++tmp_x)
        ;

    /* Bounds check */
    if (len_y >= len_str)
        return str;

    /* reset tmp pointers */
    tmp_y = y;
    tmp_x = x;

    for (tmp_str = str ; *tmp_str; ++tmp_str)
        if(*tmp_str == *tmp_x) {
            /* save tmp_str */
            for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)
                if (*(tmp_x+1) == '\0' && ((dummy_ptr-str+len_y) < len_str)){
                    /* Reached at the end of x, we got something to replace 
                     * then!
                     * Copy y only if there is enough room for it
                     */
                    for(tmp_y=y; *tmp_y; ++tmp_y, ++tmp_str)
                        *tmp_str = *tmp_y;
            }
        /* reset tmp_x */
        tmp_x = x;
        }

    return str;
}

它并不完全符合您的要求,但会让您了解如何完成任务。

在上面的代码中,for循环

for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)

做你想要的。它从源字符串的开头(for循环的初始化)开始,然后在其逻辑检查部分中比较指针 tmp_x和dummy_ptr 指向的当前字符。最后,循环递增两个指针以遍历整个字符串。

这是搜索字符串而不是字符串中的字符串的另一个示例。此代码也来自zString library

/* First if check can be omitted to improve the performance */
int zstring_search_chr(char *token,char s){
    if (!token || s=='\0')
        return 0;

    for (;*token; token++)
        if (*token == s)
            return 1;

    return 0;
}