创建堆一个结构? [英] Creating a struct on the heap?

查看:147
本文介绍了创建堆一个结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经指示通过创建堆上的一个String结构编写一个模型的strdup持有的源代码的副本。我想我已经成功地$ C $光盘的strdup,但我不知道我是否已经创建的堆的Struct ...

 的typedef
结构字符串{
    INT长;
    INT能力;
    无符号的检查;
    炭ptr的[0];
}字符串;字符* modelstrdup(字符* SRC){
    INT容量= 0,长度为0,I = 0;
    字符*串;
    而(SRC [长度]!='\\ 0'){
    长++;
    }
    容量=长度;
    字符串=的malloc(sizeof的(字符串)+容量+ 1);
    而(I<长度){
    字符串[我] = SRC [I]
    我++;
    }
    字符串[I + 1] ='\\ 0';    返回的字符串;
}


解决方案

是的,你已经创建堆一个结构。您还没有正确填充它,你将要面对的将其删除的问题 - 我不知道作业是否涵盖了与否。既然这样,你就更有可能得到内存损坏或者,如果你运气好,内存泄漏,而不是释放这些字符串之一。

code,与标准C89和C99

工作

您code,有点搞掂......

 的typedef
结构字符串{
    INT长;
    INT能力;
    字符* PTR;
}字符串;字符* modelstrdup(字符* SRC){
    INT长度= strlen的(SRC);
    字符*空间=的malloc(sizeof的(字符串)+长度+ 1);
    //字符串*字符串=空间; //原始code - 编译器并不热衷于它
    字符串*字符串=(字符串*)空间;
    断言(空间!= 0);
    与字符串> PTR =空格+的sizeof(字符串); //或者sizeof(*字符串)
    与字符串>长度=长度;
    与字符串>容量=长度+ 1;
    的strcpy(与字符串> PTR,SRC);
    返回与字符串> PTR;
}

这code将在C89工作,以及C99(除C99 / C ++评论)。你也许可以优化它与'结构黑客工作(保存在结构的指针 - 但前提是你有一个C99编译器)。断言是次优的错误处理。在code没有抵御输入一个空指针。在这种情况下,无论是长度也没有能力提供任何好处 - 必须有在套件中的其他功能,这将能够使用该信息

由于已经暗示,你要面对删除管柱结构问题时,递回的值不是一个字符串指针。你有一些微妙的指针调整做出。


code,与标准C99仅

工作

在C99,节6.7.2.1第16段介绍了灵活数组成员:


  

作为一个特例,一个结构的一个以上的命名构件的最后一个元件可
  有一个不完整的数组类型;这就是所谓的灵活数组成员。有两个
  例外,柔性阵列构件被忽略。首先,该结构的大小应
  等于替换的其它相同结构的最后一个元件的偏移
  灵活的数组成员与未指定长度的数组。 106)其次,当一个。 (或 - >)
  操作者具有左操作数是(指针)具有柔性阵列构件的结构
  而该成员,它的行为,如果该成员被替换右边的操作数名
  同,不会使结构最长阵列(具有相同的元素类型)
  比大物体被访问;该数组的偏移量应保持的的
  柔性阵列构件,即使这会从该替换阵列的不同。如果这
  数组就没有的元素,它的行为就好像它有一个元素,但该行为是
  未定义如果任何试图访问该元件或生成的指针1过去
  吧。


  
  

106 的长度是不确定的,以允许的事实,实现方式可以得到阵列成员不同
  根据它们的长度比对。


使用'结构黑客或灵活数组成员',你的code将变成:

 的typedef
结构字符串{
    INT长;
    INT能力;
    CHAR PTR [];
}字符串;字符* modelstrdup(字符* SRC){
    INT长度= strlen的(SRC);
    字符串*字符串=的malloc(sizeof的(字符串)+长度+ 1);
    断言(字符串!= 0);
    与字符串>长度=长度;
    与字符串>容量=长度+ 1;
    的strcpy(与字符串> PTR,SRC);
    返回与字符串> PTR;
}

这code被接受了由GCC 4.0.1清洁除了对功能(选项-Wall -Wextra')的声明。在previous code需要在铸造'字符串*字符串=(字符串*)空间;告诉我是什么意思我说的编译器;我现在已经修复了,并给出了评语,现出了。


使用非标准扩展C89和C99

code指定ISO C标准,并要求迂腐精度 -

零大小的数组符号是由GCC,除非你捅它很难接受。这code,因此,除非你使用编译OK'的gcc -Wall -std -Wextra C99 = -pedantic':

 的#include<&ASSERT.H GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;的typedef
结构字符串{
    INT长;
    INT能力;
    炭ptr的[0];
}字符串;字符* modelstrdup(字符* SRC){
    INT长度= strlen的(SRC);
    字符串*字符串=的malloc(sizeof的(字符串)+长度+ 1);
    断言(字符串!= 0);
    与字符串>长度=长度;
    与字符串>容量=长度+ 1;
    的strcpy(与字符串> PTR,SRC);
    返回与字符串> PTR;
}

但是,你不应该正在非标准扩展C语言训练的你有标准C的基础知识这是完全不公平的,你吃透之前;你不能告诉你被告知这样做是否是明智的,但你的导师不应该被强迫你使用非标准的东西来误导你。即使他们提醒你一个事实,即它是非标准的,这是不公平的你。 C是足够努力地学习,而无需学习调皮的东西,有些编译器特有的。

I've been instructed to write a model strdup by creating a String struct on the heap the holds a copy of the source. I think I have successfully coded the strdup, but I'm not sure if I've created a Struct on the heap...

typedef 
struct String {
    int length;
    int capacity;
    unsigned check;
    char ptr[0];
} String;

char* modelstrdup(char* src){
    int capacity =0, length=0, i = 0 ;
    char *string;
    while ( src[length] != '\0'){
    	length++;
    }
    capacity = length;
    string = malloc(sizeof(String) + capacity + 1);
    while ( i < length ){
    	string[i] = src[i];
    	i++;
    }
    string[i+1] = '\0';

    return string;
}

解决方案

Yes, you've created a struct on the heap. You haven't populated it correctly, and you are going to face problems deleting it - I'm not sure whether the homework covered that or not. As it stands, you're more likely to get memory corruption or, if you're lucky, a memory leak than to release one of these strings.

Code that works with standard C89 and C99

Your code, somewhat fixed up...

typedef 
struct String {
    int length;
    int capacity;
    char *ptr;
} String;

char* modelstrdup(char* src){
    int length = strlen(src);
    char *space = malloc(sizeof(String) + length + 1);
    //String *string = space;  // Original code - compilers are not keen on it
    String *string = (String *)space;
    assert(space != 0);
    string->ptr = space + sizeof(String);  // or sizeof(*string)
    string->length = length;
    string->capacity = length + 1;
    strcpy(string->ptr, src);
    return string->ptr;
}

This code will work in C89 as well as C99 (except for the C99/C++ comments). You can probably optimize it to work with the 'struct hack' (saves a pointer in the structure - but only if you have a C99 compiler). The assert is sub-optimal error handling. The code doesn't defend itself against a null pointer for input. In this context, neither the length nor the capacity provides any benefit - there must be other functions in the suite that will be able to make use of that information.

As already intimated, you are going to face problems deleting the string structure when the value handed back is not a pointer to the string. You have some delicate pointer adjustments to make.


Code that works with standard C99 only

In C99, section 6.7.2.1 paragraph 16 describes 'flexible array members':

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. With two exceptions, the flexible array member is ignored. First, the size of the structure shall be equal to the offset of the last element of an otherwise identical structure that replaces the flexible array member with an array of unspecified length.106) Second, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it.

106 The length is unspecified to allow for the fact that implementations may give array members different alignments according to their lengths.

Using the 'struct hack' or 'flexible array member', your code could become:

typedef 
struct String {
    int length;
    int capacity;
    char ptr[];
} String;

char* modelstrdup(char* src){
    int length = strlen(src);
    String *string = malloc(sizeof(String) + length + 1);
    assert(string != 0);
    string->length = length;
    string->capacity = length + 1;
    strcpy(string->ptr, src);
    return string->ptr;
}

This code was accepted as clean by GCC 4.0.1 apart from a declaration for the function (options '-Wall -Wextra'). The previous code needs a cast on 'String *string = (String *)space;' to tell the compiler I meant what I said; I've now fixed that and left a comment to show the original.


Code that uses a non-standard extension to C89 and C99

The zero-size array notation is accepted by GCC unless you poke it hard - specify the ISO C standard and request pedantic accuracy. This code, therefore, compiles OK unless you get to use 'gcc -Wall -Wextra -std=c99 -pedantic':

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

typedef
struct String {
    int length;
    int capacity;
    char ptr[0];
} String;

char* modelstrdup(char* src){
    int length = strlen(src);
    String *string = malloc(sizeof(String) + length + 1);
    assert(string != 0);
    string->length = length;
    string->capacity = length + 1;
    strcpy(string->ptr, src);
    return string->ptr;
}

However, you should not be being trained in non-standard extensions to the C language before you have a thorough grasp of the basics of standard C. That is simply unfair to you; you can't tell whether what you're being told to do is sensible, but your tutors should not be misguiding you by forcing you to use non-standard stuff. Even if they alerted you to the fact that it is non-standard, it is not fair to you. C is hard enough to learn without learning tricksy stuff that is somewhat compiler specific.

这篇关于创建堆一个结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆