最好/最干净的是对动态分配的变量进行错误检查

问题描述 投票:0回答:1

我正在开发一个 Python C 项目,该项目涉及一些动态分配的结构,例如队列和线程结构。我主要是想提高可读性。它看起来像这样:

#include <Python.h>
#include <stdlib.h>

typedef struct Queue;
typedef struct Control;
typedef struct Logging;
typedef struct Args;

void cleanupQueue(Queue *q);
void cleanupControl(Control *c);
void cleanupLogging(Logging *l);
void cleanupArgs(Args *a);
static PyObject *pycalledfunction(){
  Queue *queue = (Queue *) malloc(sizeof(Queue));
  if(!queue){
    PyErr_SetString(type, message);
    return NULL;
  }
  // initialize queue and fill
  
  Control *control = (Control *) malloc(sizeof(Control));
  if(!control){
    cleanupQueue(queue);
    PyErr_SetString(type, message);
    return NULL;
  }
  // initialize control
  
  Logging *logging = (Logging *) malloc(sizeof(Logging));
  if(!logging){
    cleanupControl(control);
    cleanupQueue(queue);
    PyErr_SetString(type, message);
    return NULL;
  }
  // initialize logging
  
  Args *args = (Args *) malloc(sizeof(Args));
  if(!logging){
    cleanupLogging(logging);
    cleanupControl(control);
    cleanupQueue(queue);
    PyErr_SetString(type, message);
    return NULL;
  }
  // initialize and fill args with the other structs
  
  // Note: I guess I could check if they all exist before doing work with them here but I was unsure if that is a good practice since I am loading them into the args and am keen on getting the correct error message.
  
  // bunch of work here
  
  cleanupQueue(queue);
  cleanupControl(control);
  cleanupLogging(logging);
  cleanupArgs(args);
  return obj;
}

现在,只要正确清理分配的内存,这段代码就可以正常工作;尽管它稍微降低了代码的流程及其整体可读性,但我仍然希望在一定程度上改进我的结构化实践。我在那里留下了一张便条,标记我可以在做任何工作之前检查每个结构(将所有检查放在同一个地方),但我觉得这会导致相同的流程。

有什么方法可以确保在改进代码结构的同时返回正确的错误吗?

python c
1个回答
0
投票

您可以拿出好的 ol'

goto
(这是
goto
的一个有效用例):

PyObject *main()
{
  Queue *queue = malloc(sizeof *queue);

  if (!queue){
      goto fail_queue;
  }
  
  Control *control = malloc(sizeof *control);

  if (!control){
      goto fail_control;
  }
  
  Logging *logging = malloc(sizeof *logging);

  if (!logging){
      goto fail_logging;
  }
  
  Args *args = malloc(sizeof *args);

  if (!args){
      goto fail_args;
  }

  cleanupQueue(queue);
  cleanupControl(control);
  cleanupLogging(logging);
  cleanupArgs(args);
  return obj;
  
fail_args:
  cleanupLogging(logging);
fail_logging:
    cleanupControl(control);
fail_control:
    cleanupQueue(queue);
fail_queue:
    PyErr_SetString(type, message);
    return NULL;
}

我的标签可能不够有创意,请随意重命名。

© www.soinside.com 2019 - 2024. All rights reserved.