C - 拆分减慢我的电脑速度

时间:2016-09-19 11:01:35

标签: c arrays pointers split double-pointer

我正在尝试编写一个包含多个单词的char数组的分割,并将每个单词分成它们自己的较小的char数组。较小的char数组的所有指针都保存在指针数组中,因此我可以返回一个双指针。

您可以查看我的代码,看看是否有任何错误。当我尝试运行我的程序时,我的计算机逐渐变慢,3-4秒后我无法移动鼠标或alt + f4我的编辑器。所以有些事情必须严重错误!

此外,我对C编程完全陌生,所以我肯定会在那里犯一个愚蠢的错误。

char **split(char *s) {

char **result;
int wrd_cnt = 2; //I'm adding NULL at the end of the pointer-array.


//Counts the number of words to allocate memory for the pointer-array.
for(int i = 0; i < strlen(s); i++) {
    if(s[i] == ' ') {
        wrd_cnt++;
    }
}
result = malloc(wrd_cnt * sizeof(char*));

//Counts letters in each word to allocate memory for every single small char-array with malloc.
for(int i = 0; i < strlen(s); i++) {
    for(int j = 0; j < (wrd_cnt); j++) {
        int char_cnt = 0;
        for(int k = 0; s[i] != ' ' || s[i] != '\0'; k++, i++) {
            char_cnt++;
            result[j] = malloc(char_cnt * sizeof(char));
        }
    }
}

//Puts each word into their own place in the pointer array.
for(int i = 0; i < strlen(s); i++) {
    for(int j = 0; j < (wrd_cnt); j++) {
        for(int k = 0; s[i] != ' ' || s[i] != '\0'; k++, i++) {
            result[j][k] = s[i];
        }
    }
}

result[wrd_cnt-1] = NULL;
return result;
}

2 个答案:

答案 0 :(得分:1)

在这种情况下,可以删除使用j和k的循环,而是在处理s数组时基于i循环递增和重置i,j和char_cnt,类似于您在第一个循环中对wrd_cnt所做的操作< / p>

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

char **split(char *s);

int main ( void) {
    char **output = NULL;
    int each = 0;

    char line[99] = " string to   parse for words ";
    output = split ( line);

    each = 0;
    while ( output[each]) {
        printf ( "%s\n", output[each]);
        each++;
    }
    each = 0;
    while ( output[each]) {
        free ( output[each]);
        each++;
    }
    free ( output);

    exit ( 0);
}

char **split(char *s) {

    char **result;
    int wrd_cnt = 2; //I'm adding NULL at the end of the pointer-array.
    int char_cnt = 0;
    int i = 0;
    int j = 0;
    int k = 0;

    //Counts the number of words to allocate memory for the pointer-array.
    for(i = 0; i < strlen(s); i++) {
        if(s[i] == ' ') {
            wrd_cnt++;
        }
    }
    if ( ( result = malloc(wrd_cnt * sizeof(char*))) == NULL) {
        fprintf ( stderr, "malloc failure\n");
        exit ( 1);
    }
    //Counts letters in each word to allocate memory for every single small char-array with malloc.
    char_cnt = 1;
    j = 0;
    for( i = 0; i < strlen(s); i++) {
        if ( s[i] == ' ') {
            if ( ( result[j] = malloc(char_cnt * sizeof(char))) == NULL) {
                fprintf ( stderr, "malloc failure\n");
                exit ( 1);
            }
            j++;
            char_cnt = 1;
            continue;
        }
        char_cnt++;
    }
    if ( j == wrd_cnt - 2) {
        //allocate for last word
        if ( ( result[j] = malloc(char_cnt * sizeof(char))) == NULL) {
            fprintf ( stderr, "malloc failure\n");
            exit ( 1);
        }
        j++;
        result[j] = NULL;
    }
    result[wrd_cnt - 1] = NULL;//just to make sure the last pointer is null

    //Puts each word into their own place in the pointer array.
    j = 0;
    k = 0;
    for( i = 0; i < strlen(s); i++) {
        if ( s[i] == ' ') {
            result[j][k] = '\0';//for space only so [j][0] is '\0'
            k = 0;
            j++;
            continue;
        }
        result[j][k] = s[i];
        k++;
        result[j][k] = '\0';//for last word if there is no final space in s[]
    }
    return result;
}

答案 1 :(得分:0)

除了上面的评论之外,你的代码因为你所做的所有malloc()调用而吓到我,每个单词都有一个。这意味着您还必须释放每个单词。这使程序对内存泄漏开放。

鉴于这是允许大量转换的C,您可以使用单个malloc来保存(char *)指针数组和实际的单词。

 char **split(char const *s) {

     char   **result;   // 
     char    *target;   // where in result chars stored
     size_t   s_strlen = strlen(s);  // length of s
     int      wrd_cnt = 2;    //I'm adding NULL at the end of the pointer-array.
   {
     char const *sx;
     for ( sx = s; sx = strpbrk( sx, " \t\n\r" ); sx++ )
     {
         wrd_cnt++;
     }
   }

     result = malloc( (wrd_cnt * sizeof(char *)) + s_strlen + 2 );
                                         /* allow for \0 and possible ' ' */

     target = (char *)(result + wrd_cnt);  /* where to save words */
     strcpy( target, s );       /* copy to target known to be big enough */
     if ( s_strlen > 0 && target[s_strlen-1] != ' ' )
         strcat( target + s_strlen, " " );  /* assure ends in space */

   {
     char   *tx, *tnext;
     int     n;
     n = 0;
     for ( tx = target; tnext = strpbrk( tx, " \t\n\r" ); tx = tnext + 1 )
     {
         result[n++] = tx;      /* remember pointer */
         *tnext = '\0';         /* terminate word */
     }
     result[n] = NULL;          /* null termination */
   }

     return result;
 }