2

我正在为 C 类编写一个程序,但我已经到了不知道该做什么的地步。我们正在实现一个字符串库类型。

我有我的头文件(MyString.h)

typedef struct {
    char *buffer;
    int length;
    int maxLength;
} String;

String *newString(const char *str);

实现函数的文件 (MyString.c)

#include <stdlib.h>
#include <stdio.h>
#include "MyString.h"

String *newString(const char *str) {

// Allocate memory for the String
String *newStr = (String*)malloc(sizeof(String));

if (newStr == NULL) {
    printf("ERROR: Out of memory\n");
    return NULL;
}   

// Count the number of characters
int count;
for (count = 0; *(str + count) != '\0'; count++);
count++;

// Allocate memory for the buffer
newStr->buffer = (char*)malloc(count * sizeof(char));

if (newStr->buffer == NULL) {
    printf("ERROR: Out of memory\n");
    return NULL;
}

// Copy into the buffer
while (*str != '\0')
    *(newStr->buffer++) = *(str++);
*(++newStr->buffer) = '\0';

// Set the length and maximum length
newStr->length = count;
newStr->maxLength = count;

printf("newStr->buffer: %p\n",newStr->buffer); // For testing purposes

return newStr;
}

和一个测试人员(main.c)

#include <stdio.h>
#include "MyString.h"

main() {
char str[] = "Test character array";

String *testString = newString(str);

printf("testString->buffer: %p\n",testString->buffer); // Testing only
}

问题是,即使 testString 指向在 newString() 中创建的字符串,它们的缓冲区指向不同的内存地址。这是为什么?

提前致谢

4

5 回答 5

3

通过使用*(++newStr->buffer)and *(newStr->buffer++),您newStr->buffer实际上将指向字符串的末尾。您需要这样修改代码:

#include <stdlib.h>
#include <stdio.h>
#include "MyString.h"

String *newString(const char *str) {
    // Allocate memory for the String
    String *newStr = (String*)malloc(sizeof(String));

    if (newStr == NULL) {
        printf("ERROR: Out of memory\n");
        return NULL;
    }

    // Count the number of characters
    int count;
    for (count = 0; *(str + count) != '\0'; count++);
    count++;

    // Allocate memory for the buffer
    newStr->buffer = (char*)malloc(count * sizeof(char));

    if (newStr->buffer == NULL) {
        printf("ERROR: Out of memory\n");
        return NULL;
    }

    char *pBuffer = newStr->buffer; // don't move newStr->buffer, have another pointer for that.

    // Copy into the buffer
    while (*str != '\0')
        *(pBuffer++) = *(str++);
    *pBuffer = '\0';

    // Set the length and maximum length
    newStr->length = count;
    newStr->maxLength = count;

    printf("newStr->buffer: %p\n", newStr->buffer); // For testing purposes

    return newStr;
}
于 2012-06-02T17:54:48.833 回答
3

正如其他同事已经指出的那样,您修改了分配指针,这是不可以的。这是您的示例,但翻译为更“专业”的方式。

我会将您的结构更改为:

typedef struct {
   char *buffer;
   size_t length;        /* strings and allocation in C are of type size_t not int */
   size_t alloclength;
} String;

String *newString(const char *str);

并且功能将更改为。

#include <stdlib.h>
#include <stdio.h>
#include "MyString.h"

String *newString(const char *str)
{
  // Allocate memory for the String
  String *newStr = malloc(sizeof (String));  /* No typecast of void * in C, it's bad taste. */

  if(!newStr) {
    fprintf(stderr, "ERROR: Out of memory\n");     /* Errors are meant to be printed on stderr, not stdio */
    return NULL;
  }   
  // Count the number of characters
  newStr->length = strlen(str);          /* Learn to use the stdlib, there are a lot of usefull functions */
  newStr->alloclength = newStr->length+1;
  // Allocate memory for the buffer
  newStr->buffer = malloc(newStr->alloclength);   /* sizeof (char) is by definition always 1 */
  if(!newStr->buffer) {
    fprintf(stderr, "ERROR: Out of memory\n");
    free(newStr);      
    return NULL;
  }
  // Copy into the buffer
  strcpy(newStr->buffer, str);   /* Because we already scaned the input with strlen, we can use safely the "unsafe" strcpy function. The strcpy will add the trailing 0 */
  printf("newStr->buffer: %p\n",newStr->buffer); // For testing purposes
  return newStr;
} 
于 2012-06-02T18:15:47.990 回答
2

您正在修改新创建的 String 结构内的缓冲区指针。

你应该做:

char *newBuffer = newStr->buffer;
// Copy into the buffer
while (*str != '\0')
    *(newBuffer++) = *(str++);
*(++newBuffer) = '\0';
于 2012-06-02T17:56:47.943 回答
2

问题已得到解答,但我认为您应该添加一段代码以避免内存泄漏的微妙来源:

// Allocate memory for the buffer
newStr->buffer = (char*)malloc(count * sizeof(char));

if (newStr->buffer == NULL) {
    printf("ERROR: Out of memory\n");
    free(newStr); // free the memory allocated for newStr
    return NULL;
}
于 2013-07-20T16:04:00.750 回答
1

解释很简单:您正在修改newString()函数中的缓冲区指针:

// Copy into the buffer
while (*str != '\0')
    *(newStr->buffer++) = *(str++);
*(++newStr->buffer) = '\0';

您可以在此处使用临时指针(如其他答案中建议的那样),但我建议您使用以下提供的标准函数string.h

// Count the number of characters
int count;
count = strlen(str) + 1;

// Copy into the buffer
memcpy(newString->buffer, str, count)
于 2012-06-02T18:03:56.600 回答