字符数组上的分段错误

时间:2017-06-19 21:18:43

标签: c string algorithm segmentation-fault

我需要计算一个"字符串列表"中有多少个字符串。每个字符串像往常一样以NUL字符('\0')结束,列表以两个NUL字符连续结束。

我写了一个函数,但我一直遇到分段错误:

int numStrsInList(const char* strList) {
    int count = 0;
    int flag = 0;
    if(!(*strList))
        return -1;

    while (flag != 2) {
        if (!(*strList)) {
            count++;
            flag++;
        }
        else
            flag = 0;
        strList++;
    }
    return count;
}

例如:

const char* empty = "\0";
const char* one = "Hell0 \t\n\v\f\rw0r1d\0";
const char* two = "Hello\0 \t\0";
const char* simple = "Hello\0world\0!\0";

调用例如:

numStrsInList(empty)
numStrsInList(one)
numStrsInList(two)
numStrsInList(simple)

对于此字符串,输出应为:

0
1
2
3

2 个答案:

答案 0 :(得分:4)

您的代码有几个问题......

int numStrsInList(const char* strList) {
    int count = 0;
    int flag = 0;
    if(!(*strList))      // this is not right, numStrsInList("\0") returns -1 instead of 0
        return -1;       // did you mean if (!strlist) ??

    while (flag != 2) {
        if (!(*strList)) {    // maybe using this notation if (!strlist[0]) 
            count++;          // would help in avoiding the error above
            flag++;           // c library has strlen() functions
        }                     // that are much faster and will make your code more readable
        else
            flag = 0;
        strList++;
      }
      return count;
    }

  }

比较,每个请求添加的总长度:)

int numStrsInList(const char* strList, int maxlen) 
{
   // returns the number of strings in a null terminated array of 
   // contiguous null-terminated strings.
   // maxlen is the maximum overall length of the buffer, 
   // can be 0 to defeat length checking

   const char* s;
   int result = 0;

   if (!strList) return -1;

   for (s = strlist; 
        s > (char*)1 && s[0] != 0; 
        s = (maxlen) ? (memchr(s, 0, maxlen - (s - strlist)) + 1)
                     : (s + strlen(s) + 1) )
   {
     if ((s - strlist) > maxlen) return -1;
     ++result;
   }

   return result;
}

答案 1 :(得分:2)

只需使用标题strchr中声明的标准C函数<string.h>

例如

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

size_t numStrsInList(const char *s)
{
    size_t n = 0;

    if (!(s[0] == '\0' && s[1] == '\0'))
    {
        do
        {
            s = strchr(s, '\0');
            ++n;
        } while (*++s);
    }

    return n;
}

int main( void )
{
    printf("The number of substrings is %zu\n", numStrsInList("\0"));
    printf("The number of substrings is %zu\n", numStrsInList("Hell0 \t\n\v\f\rw0r1d\0")) ;
    printf("The number of substrings is %zu\n", numStrsInList("Hello\0 \t\0"));
    printf("The number of substrings is %zu\n", numStrsInList("Hello\0world\0!\0"));
}

程序输出

The number of substrings is 0
The number of substrings is 1
The number of substrings is 2
The number of substrings is 3

不使用标准函数strchr,可以通过以下方式实现该功能

size_t numStrsInList(const char *s)
{
    size_t n = 0;

    if (!(s[0] == '\0' && s[1] == '\0'))
    {
        do
        {
            while (*s) ++s;
            ++n;
        } while (*++s);
    }

    return n;
}

考虑到例如此字符串

"\0A\0"

包含两个子字符串:"""A"。虽然此字符串"\0"不包含子字符串。 至于你的代码那么已经是这个陈述

if(!(*strList))
    return -1;

没有意义。

看来你的意思是

if(!strList)
    return -1;

指针strList不等于NULL。但是,与标准字符串函数类比,当调用者检查指针是否等于NULL时更好。