我这样做对吗? - C代码

时间:2011-11-26 20:25:17

标签: c memory dynamic allocation

当我运行它时,它表示当它真的是6时大小为4。它在这里这样做:

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;
}

6 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

在你的辅助函数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在编译时测量类型的大小;你的字符串参数将是运行时变量。

答案 2 :(得分:1)

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

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 :(得分:1)

我认为您希望sizeof执行strlen()所做的事情,或String_GetSize()所做的事情。这不是它的目的。

您在sizeof指针上执行char*,即“此char*的大小”,这与“字符串指向多长时间”不同由此char*“。大多数(如果不是全部)32位平台sizeof(char*)实际上都是4

答案 4 :(得分:0)

在C中,“string”不是真正的数据类型。 sizeof运算符采用数据类型或具有“type”作为操作数的对象。在您的情况下,对象是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 ;
}

答案 5 :(得分:0)

我认为您的func String_New出现了问题,当您将basic_string传递给String_New时,它实际上是一个指针,即char *。所以,在32位机器,sizeof(char *)是4