【问题标题】:am i doing this right? - C code我这样做对吗? - C代码
【发布时间】:2011-11-26 20:25:16
【问题描述】:

当我运行它时,它说大小是 4,而实际上是 6。它在这里执行此操作:

printf("String Size: %u\n", sizeof some_string.basic_string);

我是 c 内存分配的新手,以前从未使用过 malloc。我使用 malloc 对吗?

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

typedef struct String String;

struct String {
  char *basic_string;
};

String String_New(char basic_string[]) {
  String temp;
  temp.basic_string = (char *) malloc(sizeof basic_string);
  strcpy(temp.basic_string, basic_string);
  return temp;
}

void String_Delete(String *string) {
  free(string->basic_string);
  string->basic_string = NULL;
}

int String_GetSize(String string) {
  int i = 0, s = 0;
  while (string.basic_string[i] != '\0') {
    i++;
    s++;
  }
return s;
}

int main(int argc, char *argv[]) {
  String some_string = String_New("hello");
  printf("String Literal: %s\n", some_string.basic_string);
  printf("String Size: %u\n", sizeof some_string.basic_string);
  printf("String Length: %d\n", String_GetSize(some_string));
  String_Delete(&some_string);

  if (some_string.basic_string == NULL) {
    return 0;
  }

  return 1;
}

【问题讨论】:

  • si 中的 String_GetSize 都是多余的。我会删除 s,因为 i 是索引或循环计数器的更常见(惯用)用法。
  • 您似乎正在尝试在 C 中使用面向对象的模式。您不使用 C++(或 C# 或 Java)是否有原因?
  • 我不喜欢 java 或 c# 和 idk 为什么我不这样做是 c++
  • 不确定我是否理解您的评论。您的意思是“在 C++ 中”吗?
  • How sizeof operator works in c 的可能重复项

标签: c memory dynamic allocation


【解决方案1】:

char *basic_string; 是指向某个内存的指针,指针的大小(在 32 位系统上)为 32 位 = 4 字节。 Sizeof 不知道您在该地址保留的内存大小。

通常无法获得 malloc 保留的内存大小 - 尽管您的系统可能有一些私有调试功能来执行此操作。

【讨论】:

    【解决方案2】:

    不,String_New 中的malloc 应该使用字符串的实际运行时长度,例如

    String String_New(char basic_string[]) {
      String temp;
      int length = strlen(basic_string);
      temp.basic_string =
         (char *) malloc(length+1); /* 1 more byte for terminating \0 */
      strcpy(temp.basic_string, basic_string);
      return temp;
    }
    

    但您应该只使用 strdup 例如temp.basic_string = strdup (basic_string);

    【讨论】:

      【解决方案3】:

      在您的辅助函数 String_New() 中,当您说“sizeof(basic_string)”时,您要求的是指针的大小而不是字符串的大小,这就是为什么您得到 4 而不是 6。我想什么你想要的是这样的:-

      String String_New(const char* basic_string) {
        String temp;
        temp.basic_string = (char *) malloc(strlen(basic_string)+1);
        strcpy(temp.basic_string, basic_string);
        return temp;
      }
      

      sizeof 在编译时测量类型的大小;您的字符串参数将是运行时变量。

      【讨论】:

      • 不是strlen(basic_string),而是strlen(basic_strng)+1,所以我编辑了答案。
      【解决方案4】:

      我认为您希望 sizeof 做与 strlen() 或您的 String_GetSize() 所做的相同的事情。这不是它的目的。

      您在char* 指针上执行sizeof,即“这个char* 的大小是多少”,这是与“这个char* 指向的字符串有多长”不同的问题.在大多数(如果不是全部)32 位平台上,sizeof(char*) 实际上是4

      【讨论】:

        【解决方案5】:

        在 C 中,“字符串”不是真正的数据类型。 sizeof 运算符采用数据类型或具有“类型”作为操作数的对象。在您的情况下,对象是 some_string.basic_string,其类型为 char*,并且系统上的指针大小为 4。

        解决方案是定义您的 String 结构以具有 size 成员:

        struct String {
          char *basic_string;
          size_t length ;
        };
        

        并将分配时的大小存储在String_New()中。这将简化您的 String_GetSize() 函数并提高其效率(因为 s == i,这已经过于复杂了)。

        还要注意,在String_New() 中,basic_string 参数也是一个指针(尽管在其签名中使用了“数组语法”)。我会避免这种语法,它会产生误导,因为在 C 中,除非数组嵌入到结构中,否则不能通过副本传递数组;当作为参数传递时,数组总是“降级”为指针。此外,在任何情况下,调用者都可以传递一个指针而不是一个数组。因此,在大多数情况下,您分配的内存太少(4 个字节)。您应该使用strlen() 或您最初在String_GetSize() 中使用的方法来确定长度。

        String String_New(char* basic_string) 
        {
          String temp;
          temp.length = strlen( basic_string ) ;
          temp.basic_string = (char *) malloc( temp.length + 1 );
        
          strcpy(temp.basic_string, basic_string);
          return temp;
        }
        
        size_t String_GetSize(String string) 
        {
            return string.length ;
        }
        

        【讨论】:

          【解决方案6】:

          我认为你的函数String_New有问题,当你将basic_string传递给String_New时,它实际上是一个指针,即char *。所以,在32位机器中,sizeof(char *)是4

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-08-13
            • 2023-03-19
            • 1970-01-01
            • 2022-07-11
            • 2015-01-13
            • 2012-04-08
            • 2015-06-09
            • 2014-06-28
            相关资源
            最近更新 更多