将字符串拆分为140个字符块

时间:2014-10-28 11:03:34

标签: c string segmentation-fault

这是我的功能:

char** split_string(char* message){

  int i = 0;
  int j = 0;
  int numberOfMsgs = 0;
  int charsInLastMsg = (int)(strlen(message)%140);


  if((int)strlen(message) > 140*4){
    return NULL;
  }

  if((int)(strlen(message)%140)){
    numberOfMsgs = (int)(strlen(message)/140) + 1;
  }
  else{
    numberOfMsgs = (int)(strlen(message)/140);
  }

  printf("message length = %d, we will have %d messages, and last msg will have %d characters\n", (int)strlen(message), numberOfMsgs, charsInLastMsg);


  char **m = malloc(numberOfMsgs * sizeof(char*));
  for (j =0 ; j <= numberOfMsgs; j++){
    m[j] = malloc(141 * sizeof(char));
  }

  for(i=0;i<numberOfMsgs;i++){
    if(i == numberOfMsgs - 1){

      memcpy(m[i], message + (140*i), charsInLastMsg);
      m[i][charsInLastMsg] = '\0';
    }
    else{
      memcpy(m[i], message + (140*i), 140);
      m[i][140] = '\0';

    }
    printf("m%d = %s\n", i, m[i]);
  }
  return m;
}

我这样称呼:

char* message = "1, 2, 3, 4, 5, 6, 7, 8, 9 and 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100.";

int i=0;
char** m = split_string(message);
while(*m){
  printf("string%d = %s\n", i, m[i]);       //Problem at this line.
  m++;
}

但是,当我运行它时,我在上面指定的行上遇到了分段错误。如果我不打印,程序运行正常,所以我认为函数split_string()没问题。

我做错了什么?我是新手,请帮助。

/ ************************************预计O / P ****** **************************** /

我希望将字符串拆分为140个字符串,如下所示:

string0 = 1, 2, 3, 4, 5, 6, 7, 8, 9 and 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36
string1 = , 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71
string2 = , 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100.

4 个答案:

答案 0 :(得分:2)

您的代码中存在多个问题。你已经修好了一些。

您的客户代码

while (*m) {
    printf("string%d = %s\n", i, *m);
    i++;
    m++;
}

(我已经冒昧地用m[i]替换i始终为0 *m}表示char-pointer数组mNULL -terminated,即NULL指针指示字符串列表的结尾。 (就像'\0'字符表示字符串的结尾一样。)

但您的函数split_string并未在末尾添加NULL指针:您的客户端代码将读取超出有效内存的数据。

char **m = malloc(numberOfMsgs * sizeof(char*));

在这里,您应该为(numberOfMsgs + 1)分配NULL个字符串,一个额外的字符串。

for (j =0 ; j <= numberOfMsgs; j++){
    m[j] = malloc(141 * sizeof(char));
}

在这里,您应该只分配numberOfMsgs个字符串。 NULL字符串不必分配,只需设置为NULL

m[numberOfMsgs] = NULL;

最后,你应该释放分配的内存。在您的情况下,您不能这样做,因为您已经增加(并因此更改)基指针m。操作系统无法释放内存,因为新的m未被内存分配器注册。

所以,例如:

char **m = split_string(message, 140);
int i = 0;

while (m[i]) {
    printf("%d: '%s'\n", i, m[i]);
    free(m[i]);
    i++;
}

free(m);

答案 1 :(得分:1)

你的while循环是一个无限循环。您正在测试永远不会更改的表达式*m,因此您将继续增加i,最终m[i]将引用尚未分配的内存。

答案 2 :(得分:1)

这是使用数组的问题,有关其大小的信息应存储在某个地方,你永远不会知道查看char **它有多少成员。

这就是为什么存在以空字符结尾的字符串(c字符串),NULL字符标记其结束的原因,所以你必须遍历整个字符串,直到找到NULL来知道它的长度。

无论如何,我建议您将split_string()功能修改为:

char** split_string(char* message, size_t * n_msgs) {
   //...
   *n_msgs = numberOfMsgs;
   ///
}

然后:

size_t msgs = 0;
char** m = split_string(message, &msgs);
//...

答案 3 :(得分:1)

您应该更改for (j =0 ; j <= numberOfMsgs; j++){ m[j] = malloc(141 * sizeof(char));

for (j =0 ; j < numberOfMsgs; j++){
m[j] = malloc(141 * sizeof(char));