Local variables and memory in c

二次信任 提交于 2021-01-29 03:04:17

问题


I'm somewhat new to C and am wondering about certain things about memory allocation. My function is as follows:

size_t count_nwords(const char* str) {
    //char* copied_str = strdup(str);  // because 'strtok()' alters the string it passes through
    char copied_str[strlen(str)];
    strcpy(copied_str, str);
    size_t count = 1;

    strtok(copied_str, " ");
    while(strtok(NULL, " ") != 0) {
        count++;
    }

    //free(copied_str);

    return count;
}

This function counts the amount of words in a string (the delimiter is a space, ie ""). I do not want the string passed in argument to be modified.

I have two questions:

  1. Should the strdup() way (which is the commented part in the code) be preferred over the strcpy() one? My understanding is that strcpy() is sufficient and faster, but I am not certain.
  2. Since no memory is allocated for the size_t value to be returned (it's a local variable), should it be done in order to ensure the function is robust? Or is using size_t nwords = count_nwords(copied_input); completely safe and will always properly get the returned value?

Thank you!

EDIT: I've accepted the only answer that concerned my questions precisely, but I advise reading the other answers as they provide good insights regarding errors I had made in my code.


回答1:


  1. Should the strdup() way (which is the commented part in the code) be preferred over the strcpy() one? My understanding is that strcpy() is sufficient and faster, but I am not certain.

Your solution is clean and works well so don't bother. The only point is that you are using VLA which is now optional, then using strdup would be less standard prone. Now regarding performance, as it is not specified how VLAs are implemented, performance may vary from compiler/platform to compiler/platform (gcc is known to use stack for VLAs but any other compiler may use heap). We only know that strdup allocates on the heap, that's all. I doubt that performance problem will come from such a choice.

Note: you allocation size is wrong and should be at least strlen(str)+1.

  1. Since no memory is allocated for the size_t value to be returned (it's a local variable), should it be done in order to ensure the function is robust? Or is using size_t nwords = count_nwords(copied_input); completely safe and will always properly get the returned value?

Managing return values and memory suitable for is a concern of the compiler. Usually, these values are transfered on/from the stack (have some reading on "stack frame"). As you may suspect, space is allocated on the stack for it just before the call and is deallocated after the call (as soon as you discard or copy the returned value).




回答2:


Failure to account for the null character

// char copied_str[strlen(str)];
char copied_str[strlen(str) + 1];
strcpy(copied_str, str);

Wrong algorithm

Even with above fix, code returns 1 with count_nwords(" ")

Unnecessary copying of string

strtok() not needed here. A copy of the string is not needed.


Alternative: walk the string.

size_t count_nwords(const char* str) {
  size_t count = 0;
  while (*str) {
    while (isspace((unsigned char) *str)) {
      str++; 
    }
    if (*str) {
      count++;
      while (!isspace((unsigned char) *str) && *str) {
        str++; 
      } 
    }
  }
  return count;
}



回答3:


Another option is the state-loop approach where you continually loop over each character keeping track of the state of your count with a simple flag. (you are either in a word reading characters or you are reading spaces). The benefit being you have only a single loop involved. A short example would be:

size_t count_words (const char *str)
{
    size_t words = 0;
    int in_word = 0;

    while (*str) {
        if (isspace ((unsigned char)*str))
            in_word = 0;
        else {
            if (!in_word)
                words++;
            in_word = 1;
        }
        str++;
    }

    return words;
}

It is worth understanding all techniques. isspace requires the inclusion of ctype.h.



来源:https://stackoverflow.com/questions/54314776/local-variables-and-memory-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!